ATLAS Offline Software
Loading...
Searching...
No Matches
TGCSectorLogic.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
11#include "TrigT1TGC/TGCTMDB.h"
15#include "TrigT1TGC/TGCNSW.h"
18#include "TrigT1TGC/TGCBIS78.h"
21#include "TrigT1TGC/TGCGoodMF.h"
23
28
31
32#include <iostream>
33
34namespace LVL1TGCTrigger {
35
37 TGCRegionType regionIn, int idIn)
38 : m_bid(0),
39 m_id(idIn),
40 m_region(regionIn),
42 m_SSCController(tgcargs,this),
43 m_matrix(tgcargs,this),
44 m_pTMDB(0),
45 m_trackSelector(this),
50 m_tgcArgs(tgcargs)
51{
52 m_sideId = static_cast<LVL1TGC::TGCSide>((idIn / NumberOfModule) / NumberOfOctant);
55
59 } else {
62 }
63
64 m_nswSide = (tgcArgs()->NSWSideInfo().find('A')!=std::string::npos && m_sideId == LVL1TGC::TGCSide::ASIDE)
65 || (tgcArgs()->NSWSideInfo().find('C')!=std::string::npos && m_sideId == LVL1TGC::TGCSide::CSIDE);
66
67 m_SSCController.setRegion(regionIn);
68
69 m_matrix.setSideId(m_sideId);
70 m_mapEIFI = db->getEIFICoincidenceMap(m_sideId);
71
73
74 m_matrix.setCoincidenceLUT(db->getBigWheelCoincidenceLUT());
75 m_tileMuLUT = db->getTileMuCoincidenceLUT();
76 m_useTileMu = (m_tileMuLUT != nullptr) && m_useTileMu;
77
78 m_mapGoodMF = db->getGoodMFMap();
79 m_mapNSW = db->getNSWCoincidenceMap(m_sideId, m_octantId, m_moduleId);
80 if(tgcArgs()->USE_BIS78()) m_mapBIS78 = db->getBIS78CoincidenceMap();
81
83
84 for(int i=0; i<MaxNumberOfWireHighPtBoard; i++){
85 m_wireHighPtBoard[i] = 0;
87 }
88
89 for(unsigned int iSlot=0; iSlot<TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR; iSlot++) {
90 m_innerTrackletSlots[iSlot] = 0;
91 }
92
94 if(m_mapEIFI == 0) m_useEIFI = false;
95 m_useGoodMF = (m_mapGoodMF != nullptr);
96 if(m_mapNSW == 0) tgcArgs()->set_USE_NSW(false);
97 if(m_mapBIS78 == 0) tgcArgs()->set_USE_BIS78(false);
98}
99
102
103void TGCSectorLogic::setTMDB(std::shared_ptr<const LVL1TGC::TGCTMDB> tmdb)
104{
105 m_pTMDB = std::move(tmdb);
106 if (m_pTMDB==0) m_useTileMu = false;
107}
108
109void TGCSectorLogic::setNSW(std::shared_ptr<const LVL1TGC::TGCNSW> nsw)
110{
111 m_nsw = std::move(nsw);
112 if(m_nsw == 0) tgcArgs()->set_USE_NSW(false);
113}
114
115void TGCSectorLogic::setBIS78(std::shared_ptr<const LVL1TGC::TGCBIS78> bis78)
116{
117 m_bis78 = std::move(bis78);
118 if(m_bis78 == 0) tgcArgs()->set_USE_BIS78(false);
119}
120
122{
123 m_wireHighPtBoard[port] = highPtBoard;
125}
126
128{
129 m_stripHighPtBoard = highPtBoard;
130}
131
132void TGCSectorLogic::getTrackSelectorOutput(std::shared_ptr<TGCTrackSelectorOut> &trackSelectorOut)const
133{
134 trackSelectorOut=m_trackSelectorOut;
135}
136
138 int bidIn, bool process)
139{
140 // skip to process if want. (e.g. no hit in TGC)
141 if(!process) return;
142
143 m_bid=bidIn;
144
145 collectInput();
146
147 TGCSSCControllerOut* SSCCOut =
149#ifdef TGCDEBUG
150 SSCCOut->print();
151#endif
152 deleteHPBOut();
153
154 for(int SSCid=0; SSCid<getNumberOfSubSectorCluster(); SSCid+=1){
155 TGCRPhiCoincidenceOut* coincidenceOut = 0;
156 if(SSCCOut->hasHit(SSCid)){
157 m_matrix.clear();
158 m_matrix.setSSCId(SSCid);
159 m_matrix.inputR(SSCCOut->getR(SSCid),SSCCOut->getDR(SSCid),SSCCOut->getPtR(SSCid));
160 for(int phiposInSSC = 0 ;phiposInSSC < TGCSSCControllerOut::MaxNumberOfPhiInSSC; phiposInSSC++){
161 if(SSCCOut->hasHit(SSCid, phiposInSSC)){
162 m_matrix.inputPhi(SSCCOut->getPhi(SSCid,phiposInSSC),
163 SSCCOut->getDPhi(SSCid,phiposInSSC),
164 SSCCOut->getPtPhi(SSCid,phiposInSSC));
165 }
166 }
167 coincidenceOut = m_matrix.doCoincidence();
168 }
170 if(SSCCOut->hasHit(SSCid,true)){
171 m_matrix.clear();
172 m_matrix.setSSCId(SSCid);
173 m_matrix.inputR(SSCCOut->getR(SSCid),SSCCOut->getDR(SSCid),SSCCOut->getPtR(SSCid));
174 for(int phiposInSSC = 0 ;phiposInSSC < TGCSSCControllerOut::MaxNumberOfPhiInSSC; phiposInSSC++){
175 if(SSCCOut->hasHit(SSCid, phiposInSSC, true)){
176 m_matrix.inputPhi(SSCCOut->getPhi(SSCid,phiposInSSC,true),
177 SSCCOut->getDPhi(SSCid,phiposInSSC,true),
178 SSCCOut->getPtPhi(SSCid,phiposInSSC,true));
179 }
180 }
181
182 TGCRPhiCoincidenceOut* oredCoincidenceOut = m_matrix.doCoincidence();
183 if (oredCoincidenceOut) {
184 if(coincidenceOut) {
185 if (coincidenceOut->isSuperior(oredCoincidenceOut)) {
186 delete oredCoincidenceOut;
187 } else {
188 delete coincidenceOut;
189 coincidenceOut = oredCoincidenceOut;
190 }
191 } else {
192 coincidenceOut = oredCoincidenceOut;
193 }
194 }
195 }
196
197 if (coincidenceOut) {
198 if (m_useGoodMF) {
199 bool isgoodMF = m_mapGoodMF->test_GoodMF(m_moduleId,SSCid,coincidenceOut->getRoI());
200 coincidenceOut->setGoodMFFlag(isgoodMF);
201 }
202 }
203
205 // do coincidence with Inner Tracklet of EI, NSW, Tile, and/or RPC-BIS78
206 doInnerCoincidence(SSCid, coincidenceOut);
207
208 if (coincidenceOut) {
209 m_trackSelector.input(coincidenceOut);
210 }
211 }
212 if(SSCCOut!=0) delete SSCCOut;
213 SSCCOut=0;
214
215 // Track selector chooses up to 4 track candidates to be sent to MUCTPI.
217}
218
220{
221 for(int i = 0; i < m_SSCController.getNumberOfWireHighPtBoard(); i += 1) {
222 m_wireHighPtChipOut[i] = m_wireHighPtBoard[i]->getOutput();
223 m_wireHighPtBoard[i]->eraseOutput();
224 }
225
227 m_stripHighPtBoard->eraseOutput();
228}
229
231{
234
235 int i;
236 for( i = 0; i < m_SSCController.getNumberOfWireHighPtBoard(); i += 1) {
237 if(m_wireHighPtChipOut[i]!=0) delete m_wireHighPtChipOut[i];
239 }
240}
241
242
244{
245 std::cout<<"#SL O"<<" BID:"<<m_bid
246 <<" region:"<<((m_region == TGCRegionType::FORWARD) ? "FWD" : "END")
247 <<" SLid:"<<m_id<<" ";
248}
249
250
252 : m_bid(right.m_bid), m_id(right.m_id),
253 m_sideId(right.m_sideId),
255 m_octantId(right.m_octantId),
256 m_region(right.m_region),
260 m_SSCController(right.tgcArgs(),this),
261 m_matrix(right.tgcArgs(),this),
262 m_mapEIFI(right.m_mapEIFI),
263 m_pTMDB(right.m_pTMDB),
267 m_tgcArgs(right.m_tgcArgs)
268{
269 for(int i=0; i<MaxNumberOfWireHighPtBoard; i++){
270 m_wireHighPtBoard[i] = 0;
271 m_wireHighPtChipOut[i] = 0;
272 }
273
274 for( int i = 0; i < m_SSCController.getNumberOfWireHighPtBoard(); i += 1) {
277 }
278
279 for (unsigned int iSlot=0; iSlot<TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR; iSlot++) {
280 m_innerTrackletSlots[iSlot] = right.m_innerTrackletSlots[iSlot];
281 }
282}
283
286{
287 if ( this != &right ) {
288 m_tgcArgs = right.m_tgcArgs;
289 m_matrix = right.m_matrix;
290 m_bid =right.m_bid;
291 m_id =right.m_id;
292 m_sideId = right.m_sideId;
296 m_region=right.m_region;
298 m_mapEIFI=right.m_mapEIFI;
299 m_pTMDB=right.m_pTMDB;
304 m_useEIFI=right.m_useEIFI;
306 for( int i = 0; i < m_SSCController.getNumberOfWireHighPtBoard(); i += 1) {
309 }
310 for (unsigned int iSlot=0; iSlot<TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR; iSlot++) {
311 m_innerTrackletSlots[iSlot] = right.m_innerTrackletSlots[iSlot];
312 }
313 }
314 return *this;
315}
316
317
318void TGCSectorLogic::dec2bin(int dec, char* binstr, int length)
319{
320 for (int i=0; i<length; i++){
321 if((dec>>i) & 1)
322 binstr[length-1-i] = '1';
323 else
324 binstr[length-1-i] = '0';
325 }
326 binstr[length] ='\0';
327}
328
330{
331 for(unsigned int iSlot=0; iSlot<TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR; iSlot++) {
332 m_innerTrackletSlots[iSlot] = innerTrackletSlots[iSlot];
333 }
334}
335
336
338 if (coincidenceOut == 0) return;
339
340 int pt = coincidenceOut->getpT();
341 if (pt==0) return;
342
343 if(SSCId <= 4 && m_region == TGCRegionType::ENDCAP){ //3 detectors are used to inner coincidnece in SSC#0~4 in Endcap;
344
345 // WHICH INNER COINCIDENCE
346 // select a inner station detector which is used in inner coincidence algorithm.
347 //Defenation of innerDetectorNumber :: enum{EI=0,TILE,BIS78};
348
349 /*int innerDetectorNumber = which_InnerCoincidence();*/ //this function will be implemented.
350
351 // The below section is a tmporary method. It will be replaced with WICHINNER COINCIDENCE.
352 int pos = 4*coincidenceOut->getR() + coincidenceOut->getPhi();
353 // check if inner is used for the roi
354 bool validEI = (m_mapEIFI->getFlagROI(pos, coincidenceOut->getIdSSC(), m_sectorId) == 1);
355 // check if TileMu is used for the roi
356 bool validTileMu = (m_tileMuLUT->getFlagROI(pos, coincidenceOut->getIdSSC(), m_sectorId, m_sideId) == 1);
357 bool validBIS78 = false;
358 if(tgcArgs()->USE_BIS78()) validBIS78=(m_mapBIS78->getFlagROI(pos, coincidenceOut->getIdSSC(), m_sectorId, m_sideId) == 1);
359
360 bool isEI=false;
361 bool isTILE=false;
362 bool isBIS78=false;
363 if(m_useEIFI && validEI){isEI=doTGCEICoincidence(coincidenceOut);}
364 if(m_useTileMu && validTileMu){isTILE=doTILECoincidence(coincidenceOut); }
365 if(validBIS78){isBIS78=doTGCBIS78Coincidence(coincidenceOut); }
366
367 coincidenceOut->setInnerCoincidenceFlag(isEI || isTILE || isBIS78 || (!m_useEIFI && !validEI && !m_useTileMu && !validTileMu && !tgcArgs()->USE_BIS78() && !validBIS78));
368 } else {
369 // NSW or FI are used to inner coincidnece in SSC#5~18 in Endcap and Forward region
370 int pos = 4*coincidenceOut->getR() + coincidenceOut->getPhi();
371 bool validFI = (m_mapEIFI->getFlagROI(pos, coincidenceOut->getIdSSC(), m_sectorId) == 1) && m_region == TGCRegionType::ENDCAP;
372
373 if(tgcArgs()->USE_NSW() && m_nswSide){
374 if(tgcArgs()->FORCE_NSW_COIN()){
375 coincidenceOut->setInnerCoincidenceFlag(true);
376 }
377 else{
378 doTGCNSWCoincidence(coincidenceOut);
379 }
380 }
381 else if(!m_nswSide && validFI){
382 if(m_useEIFI){
383 coincidenceOut->setInnerCoincidenceFlag( doTGCFICoincidence(coincidenceOut) );
384 }
385 } else {
386 coincidenceOut->setInnerCoincidenceFlag(true); // TBD
387 }
388 }
389}
390
391
393 std::shared_ptr<const LVL1TGC::NSWTrigOut> pNSWOut = m_nsw->getOutput(m_region,m_sideId,m_sectorId);
394
395 // for now, if there is a hit at NSW and the side is included in the detector mask, turn on the inner coin flag
396 coincidenceOut->setInnerCoincidenceFlag( pNSWOut->getNSWeta().size()>0 && m_nswSide);
397 return;
398
399 // will implement NSW pT calculation later
400}
401
403 std::shared_ptr<const LVL1TGC::BIS78TrigOut> pBIS78Out = m_bis78->getOutput(m_sectorId);
404 if ( pBIS78Out.get() == 0 ) return false;
405 int pt=0;
406
407 pt = m_mapBIS78->TGCBIS78_pt(pBIS78Out.get(),
408 coincidenceOut->getRoI());
409
410 return (pt > 0);
411}
412
414{
416 // The function is called for Run-3 algorithim, but the Run-2 algorithm is
417 // temporarily used for instance.
419
420 bool isHitTileMu=false;
421 for(int mod=0; mod < LVL1TGC::TGCTileMuCoincidenceLUT::N_Input_TileMuModule; mod++) {
422 uint8_t maskTM = (uint8_t)(m_tileMuLUT->getTrigMask(mod, coincidenceOut->getIdSSC(), m_sectorId, m_sideId));
423 std::shared_ptr<const LVL1TGC::TGCTMDBOut> tm = m_pTMDB->getOutput(m_sideId, m_sectorId, mod);
424 isHitTileMu = isHitTileMu || this->hitTileMu(maskTM, tm->getHit6(), tm->getHit56());
425 }
426
427 return isHitTileMu;
428}
429
430
432
433 bool isHitInner=false;
434 for(unsigned int iSlot=0;iSlot<TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR; iSlot++) {
435 const TGCInnerTrackletSlot* hit = m_innerTrackletSlots[iSlot];
436
437 for (size_t reg=0;reg< TGCInnerTrackletSlot::NUMBER_OF_REGIONS; reg++){
438
439 // Wire
440 bool isHitWire = false;
441 for (size_t bit=0; bit< TGCInnerTrackletSlot::NUMBER_OF_TRIGGER_BITS; bit++){
442 isHitWire = m_mapEIFI->getTriggerBit(iSlot, coincidenceOut->getIdSSC(), m_sectorId, reg, TGCInnerTrackletSlot::WIRE, bit)
444 if(isHitWire){break;}
445 }
446
447 // Strip
448 bool isHitStrip = false;
449 for (size_t bit=0;bit< TGCInnerTrackletSlot::NUMBER_OF_TRIGGER_BITS; bit++){
450 isHitStrip = m_mapEIFI->getTriggerBit(iSlot, coincidenceOut->getIdSSC(), m_sectorId, reg, TGCInnerTrackletSlot::STRIP, bit)
452 if(isHitStrip){break;}
453 }
454
455 isHitInner = isHitWire && isHitStrip;
456 if(isHitInner){
457 return true;
458 }
459 }
460
461 }
462
463 return false;
464}
465
466
468 return doTGCEICoincidence(coincidenceOut);
469}
470
471
472bool TGCSectorLogic::hitTileMu(const uint8_t& mask, const uint8_t& hit6, const uint8_t& hit56) const
473{
479 switch(mask) {
482 break;
484 return (hit6==LVL1TGC::TGCTMDBOut::TM_HIGH);
485 break;
488 break;
490 return (hit56==LVL1TGC::TGCTMDBOut::TM_HIGH);
491 break;
492 default:
493 return false;
494 break;
495 }
496 return true;
497}
498
499} //end of namespace bracket
double length(const pvec &v)
const std::string & NSWSideInfo() const
bool getTriggerBit(const unsigned int region, const unsigned int readout, const unsigned int iBit) const
void setInnerCoincidenceFlag(bool InnerCoincidenceFlagIn)
bool isSuperior(const TGCRPhiCoincidenceOut *right) const
int getPhi(int ssc, int phipos, bool ored=false) const
int getPtPhi(int ssc, int phipos, bool ored=false) const
int getDPhi(int ssc, int phipos, bool ored=false) const
bool hasHit(int ssc, bool ored=false) const
TGCHighPtChipOut * m_wireHighPtChipOut[MaxNumberOfWireHighPtBoard]
std::shared_ptr< const TGCNSWCoincidenceMap > m_mapNSW
TGCRPhiCoincidenceMatrix m_matrix
void dec2bin(int dec, char *binstr, int length)
void setTMDB(std::shared_ptr< const LVL1TGC::TGCTMDB > tmdb)
bool doTILECoincidence(TGCRPhiCoincidenceOut *coincidenceOut)
std::shared_ptr< const LVL1TGC::TGCBIS78CoincidenceMap > m_mapBIS78
std::shared_ptr< const LVL1TGC::TGCNSW > m_nsw
void doInnerCoincidence(const SG::ReadCondHandleKey< TGCTriggerData > &readCondKey, int SSCId, TGCRPhiCoincidenceOut *coincidenceOut)
TGCSectorLogic & operator=(const TGCSectorLogic &right)
void setNSW(std::shared_ptr< const LVL1TGC::TGCNSW > nsw)
void setStripHighPtBoard(TGCHighPtBoard *highPtBoard)
const LVL1TGC::TGCEIFICoincidenceMap * m_mapEIFI
bool doTGCEICoincidence(TGCRPhiCoincidenceOut *coincidenceOut)
const TGCInnerTrackletSlot * m_innerTrackletSlots[TGCInnerTrackletSlotHolder::NUMBER_OF_SLOTS_PER_TRIGGER_SECTOR]
void setBIS78(std::shared_ptr< const LVL1TGC::TGCBIS78 > bis78)
std::shared_ptr< TGCTrackSelectorOut > m_trackSelectorOut
std::shared_ptr< const LVL1TGC::TGCBIS78 > m_bis78
TGCSectorLogic(TGCArguments *, const TGCDatabaseManager *db, TGCRegionType regionIn, int id)
std::shared_ptr< const LVL1TGC::TGCGoodMF > m_mapGoodMF
void setInnerTrackletSlots(const TGCInnerTrackletSlot *innerTrackletSlots[])
void clockIn(const SG::ReadCondHandleKey< TGCTriggerData > &readCondKey, int bidIn, bool process=true)
std::shared_ptr< const LVL1TGC::TGCTileMuCoincidenceLUT > m_tileMuLUT
bool doTGCFICoincidence(TGCRPhiCoincidenceOut *coincidenceOut)
TGCHighPtChipOut * m_stripHighPtChipOut
bool doTGCBIS78Coincidence(TGCRPhiCoincidenceOut *coincidenceOut)
void getTrackSelectorOutput(std::shared_ptr< TGCTrackSelectorOut > &trackSelectorOut) const
std::shared_ptr< const LVL1TGC::TGCTMDB > m_pTMDB
void doTGCNSWCoincidence(TGCRPhiCoincidenceOut *coincidenceOut)
bool hitTileMu(const uint8_t &mask, const uint8_t &hit6, const uint8_t &hit56) const
void setWireHighPtBoard(int port, TGCHighPtBoard *highPtBoard)
TGCHighPtBoard * m_wireHighPtBoard[MaxNumberOfWireHighPtBoard]
const std::string process
TGCSide
The sides of TGC (A- or C-side)