ATLAS Offline Software
Loading...
Searching...
No Matches
TgcRdoToPrepDataToolMT.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
9#include <algorithm>
10#include <cfloat>
11#include <memory>
12
13#include "GaudiKernel/ThreadLocalContext.h"
18#include "TrkSurfaces/Surface.h"
20
21namespace {
22using namespace xAOD::P4Helpers;
23}
24//================ Initialization =================
25
27 ATH_CHECK(m_idHelperSvc.retrieve());
28
29 m_outputprepdataKeys.resize(NBC_HIT + 1);
30 for (int ibc = 0; ibc < NBC_HIT + 1; ibc++) {
31 int bcTag = ibc + 1;
32 std::ostringstream location;
33 location << m_outputCollectionLocation.value()
34 << (bcTag == TgcDigit::BC_PREVIOUS ? "PriorBC" : "")
35 << (bcTag == TgcDigit::BC_CURRENT ? "" : "")
36 << (bcTag == TgcDigit::BC_NEXT ? "NextBC" : "")
37 << (bcTag == (NBC_HIT + 1) ? "AllBCs" : "");
38 m_outputprepdataKeys.at(ibc) = location.str();
39 }
40
42 for (int ibc = 0; ibc < NBC_TRIG; ibc++) {
43 int bcTag = ibc + 1;
44 std::ostringstream location;
45 location << m_outputCoinCollectionLocation.value()
46 << (bcTag == TgcDigit::BC_PREVIOUS ? "PriorBC" : "")
47 << (bcTag == TgcDigit::BC_NEXT ? "NextBC" : "")
48 << (bcTag == TgcDigit::BC_NEXTNEXT ? "NextNextBC" : "");
49 m_outputCoinKeys.at(ibc) = location.str();
50 }
51
52 ATH_CHECK(m_outputCoinKeys.initialize());
53 ATH_CHECK(m_outputprepdataKeys.initialize());
54 ATH_CHECK(m_muDetMgrKey.initialize());
55 ATH_CHECK(m_cablingKey.initialize());
56
57 // check if initializing of DataHandle objects success
58 ATH_CHECK(m_rdoContainerKey.initialize());
59
60
61 // Build names for the keys same as done for output containers
62 if (not m_prdContainerCacheKeyStr.empty()) {
64 for (int ibc = 0; ibc < NBC_HIT + 1; ibc++) {
65 int bcTag = ibc + 1;
66 std::ostringstream location;
67 location << m_prdContainerCacheKeyStr.value()
68 << (bcTag == TgcDigit::BC_PREVIOUS ? "PriorBC" : "")
69 << (bcTag == TgcDigit::BC_CURRENT ? "" : "")
70 << (bcTag == TgcDigit::BC_NEXT ? "NextBC" : "")
71 << (bcTag == (NBC_HIT + 1) ? "AllBCs" : "");
72 m_prdContainerCacheKeys.at(ibc) = location.str();
73 ATH_MSG_DEBUG(location.str());
74 }
75 }
76
77 if (not m_coinContainerCacheKeyStr.empty()) {
79 for (int ibc = 0; ibc < NBC_TRIG; ibc++) {
80 int bcTag = ibc + 1;
81 std::ostringstream location;
82 location << m_coinContainerCacheKeyStr.value()
83 << (bcTag == TgcDigit::BC_PREVIOUS ? "PriorBC" : "")
84 << (bcTag == TgcDigit::BC_NEXT ? "NextBC" : "")
85 << (bcTag == TgcDigit::BC_NEXTNEXT ? "NextNextBC" : "");
86 m_coinContainerCacheKeys.at(ibc) = location.str();
87 ATH_MSG_DEBUG(location.str());
88 }
89 }
90
91 // Only initialise if we passed in the cache name
93 not m_prdContainerCacheKeyStr.empty()));
95 not m_coinContainerCacheKeyStr.empty()));
96
97 ATH_CHECK(m_xAODKey.initialize(!m_xAODKey.empty()));
98 return StatusCode::SUCCESS;
99}
100
101//================ Finalization ===================
102
104 ATH_MSG_INFO("finalize(): input RDOs->output PRDs ["
105 << "Hit: " << m_nHitRDOs << "->" << m_nHitPRDs << ", "
106 << "Tracklet: " << m_nTrackletRDOs << "->" << m_nTrackletPRDs
107 << ", " << "TrackletEIFI: " << m_nTrackletEIFIRDOs << "->"
108 << m_nTrackletEIFIPRDs << ", " << "HiPt: " << m_nHiPtRDOs
109 << "->" << m_nHiPtPRDs << ", " << "SL: " << m_nSLRDOs << "->"
110 << m_nSLPRDs << "]");
111
112 return AthAlgTool::finalize();
113}
114
115//================ Decoding =================================================
117 const EventContext&, const std::vector<uint32_t>& /*robIds*/) const {
118 ATH_MSG_FATAL("ROB based decoding is not supported....");
119 return StatusCode::FAILURE;
120}
121template <class ContType, class CollType>
123 ContType& container, std::vector<std::unique_ptr<CollType>>&& coll) const {
124 for (std::unique_ptr<CollType>& toMove : coll) {
125 if (!toMove) {
126 continue;
127 }
128 const IdentifierHash hash = toMove->identifyHash();
129 auto lock = container.getWriteHandle(hash);
130 if (!lock.alreadyPresent()) {
131 ATH_CHECK(lock.addOrDelete(std::move(toMove)));
132 }
133 }
134 return StatusCode::SUCCESS;
135}
136
138 const EventContext& ctx) const {
139 if (!m_xAODKey.empty()) {
140 SG::WriteHandle handle{m_xAODKey, ctx};
141 ATH_CHECK(
142 handle.record(std::make_unique<xAOD::TgcStripContainer>(),
143 std::make_unique<xAOD::TgcStripAuxContainer>()));
144 }
145 State state{};
146 return setupState(ctx, state);
147}
148
149StatusCode Muon::TgcRdoToPrepDataToolMT::setupState(const EventContext& ctx,
150 State& state) const {
152 const unsigned hashMax = m_idHelperSvc->tgcIdHelper().module_hash_max();
153
154 for (unsigned int ibc = 0; ibc < NBC_HIT + 1; ibc++) { // +1 for AllBCs
155 // initialize with false
156 SG::WriteHandle handle{m_outputprepdataKeys[ibc], ctx};
157
158 const bool externalCachePRD =
159 m_prdContainerCacheKeys.size() > ibc &&
160 !m_prdContainerCacheKeys[ibc].key().empty();
161 if (!externalCachePRD) {
162 // record the container in storeGate
163 ATH_CHECK(
164 handle.record(std::make_unique<TgcPrepDataContainer>(hashMax)));
166 "TGC PrepData Container recorded in StoreGate with key "
167 << m_outputprepdataKeys[ibc].key());
168
169 // cache the pointer, storegate retains ownership
170 state.tgcPrepDataContainer[ibc] = handle.ptr();
171 } else {
172 // use the cache to get the container
174 ATH_CHECK(update.isValid());
175
176 ATH_CHECK(handle.record(
177 std::make_unique<Muon::TgcPrepDataContainer>(update.ptr())));
178
179 state.tgcPrepDataContainer[ibc] = handle.ptr();
180 ATH_MSG_DEBUG("Created container using cache for "
181 << m_prdContainerCacheKeys[ibc].key());
182 }
183 state.tgcPrepDataCollections[ibc].resize(hashMax);
184 }
185
187 for (unsigned int ibc = 0; ibc < NBC_TRIG; ibc++) {
188 // prepare write handle for this BC
189 SG::WriteHandle handle{m_outputCoinKeys[ibc], ctx};
190
191 const bool externalCacheCoin =
192 m_coinContainerCacheKeys.size() > ibc &&
193 !m_coinContainerCacheKeys[ibc].key().empty();
194 if (!externalCacheCoin) {
195 // No cache (offline case), just record container into store gate
196 ATH_CHECK(
197 handle.record(std::make_unique<TgcCoinDataContainer>(hashMax)));
198 } else {
199 // Using the cache (trigger case)
201 ATH_CHECK(update.isValid());
202 ATH_CHECK(handle.record(
203 std::make_unique<TgcCoinDataContainer>(update.ptr())));
204 ATH_MSG_DEBUG("Created container using cache for "
205 << m_coinContainerCacheKeys[ibc].key());
206
207 } // external cache
208
209 // cache the pointer for duration of function, storegate retains
210 // ownership
211 state.tgcCoinDataContainer[ibc] = handle.ptr();
212 state.tgcCoinDataCollections[ibc].resize(hashMax);
213
214 } // loop on BC_TRIG
215
218 return StatusCode::SUCCESS;
219}
221 const EventContext& ctx,
222 const std::vector<IdentifierHash>& requestedIdHashVect) const {
223 // Object to hold the containers for this decode call
224 State state{};
225 ATH_CHECK(setupState(ctx, state));
226
228 if (!m_xAODKey.empty()) {
230 ATH_CHECK(
231 xAODHandle.record(std::make_unique<xAOD::TgcStripContainer>(),
232 std::make_unique<xAOD::TgcStripAuxContainer>()));
233 }
234
235 int sizeVectorRequested = requestedIdHashVect.size();
236 ATH_MSG_DEBUG("decode for " << sizeVectorRequested
237 << " offline collections called");
238
239 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
240
241 std::set<const TgcRdo*> decodedRdoCollVec{}, rdoCollVec{};
242 std::array<char, 24> decodedOnlineId{};
243
244 // if TGC decoding is switched off stop here
245 if (!m_decodeData) {
247 "Stored empty container. Decoding TGC RDO into TGC PrepRawData is "
248 "switched off");
249 return StatusCode::SUCCESS;
250 }
251
252 ATH_MSG_DEBUG("Decoding TGC RDO into TGC PrepRawData");
253
254 // retrieve the collection of RDO
255 ATH_MSG_DEBUG("Retrieving TGC RDO container from the store");
256 const TgcRdoContainer* rdoContainer{};
257 ATH_CHECK(SG::get(rdoContainer, m_rdoContainerKey, ctx));
260 if (rdoContainer->empty()) {
261 // empty csm container - no tgc rdo in this event
262 ATH_MSG_DEBUG("Empty rdo container - no tgc rdo in this event");
263 return StatusCode::SUCCESS;
264 }
265
267 "Not empty rdo container in this event, the container size is "
268 << rdoContainer->size());
269
270 // select RDOs to be decoded when seeded mode is used
271 if (sizeVectorRequested != 0) {
272 unsigned int nRdo = 0;
273 const IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context(); // TGC context
274
275 for (const IdentifierHash& offlineCollHash : requestedIdHashVect) {
276 Identifier elementId;
277 int subDetectorId = 0; // 103(=0x67) for A side, 104(=0x68) for C side
278 int rodId = 0; // 1 to 12 (12-fold cabling)
279 m_idHelperSvc->tgcIdHelper().get_id(offlineCollHash, elementId, &tgcContext);
280 state.cabling->getReadoutIDfromElementID(elementId, subDetectorId, rodId);
281 // onlineId: 0 to 11 on A side and 12 to 23 on C side (12-fold cabling)
282 const uint16_t onlineId = TgcRdo::calculateOnlineId(subDetectorId, rodId);
283
284 if (decodedOnlineId.at(onlineId)) {
285 ATH_MSG_DEBUG("The ROB with onlineId "
286 << onlineId << " which contains hash "
287 << static_cast<unsigned int>(offlineCollHash)
288 << " is already decoded and skipped");
289 continue;
290 }
291
292 decodedOnlineId.at(onlineId) = true; // The ROB with this onlineId will be decoded only once
293
294 for (const TgcRdo* rdoColl : *rdoContainer) {
295 if (rdoColl->identify() == onlineId) {
296 if (!decodedRdoCollVec.count(rdoColl)) {
297 rdoCollVec.insert(rdoColl);
298 nRdo++;
299 }
300 break;
301 }
302 }
303 }
304 ATH_MSG_DEBUG("Number of RDOs to be converted is " << nRdo);
305 } // End of selection of RDOs to be decoded
306
307 // Decode Hits
308 if (sizeVectorRequested != 0) {
309 ATH_MSG_DEBUG("Start loop over rdos - seeded mode");
310 // for each RDO collection we collect up all the PRD collections and
311 // then write them once filled need a vector because we have the
312 // collections for the different bunch crosssings
313 for (const TgcRdo* rdo : rdoCollVec) {
314 for (const TgcRawData* rd : *rdo) {
315 // Since OnlineIds are not unique, need some additional
316 // filtering on offline hashId to avoid decoding RDO outside of
317 // an RoI
318 Identifier offlineId{};
320 offlineId, rd->subDetectorId(), rd->rodId(),
321 rd->sswId(), rd->slbId(), rd->bitpos())) {
322 continue;
323 }
324 const IdentifierHash tgcHashId =
325 m_idHelperSvc->moduleHash(offlineId);
326 if (std::find(requestedIdHashVect.begin(),
327 requestedIdHashVect.end(),
328 tgcHashId) == requestedIdHashVect.end()) {
329 continue;
330 }
331 selectDecoder(state, *rd, rdo);
332 }
333 decodedRdoCollVec.insert(rdo);
334 }
335 } else {
336 ATH_MSG_DEBUG("Start loop over rdos - unseeded mode");
337 for (const TgcRdo* rdoColl : *rdoContainer) {
338 if (rdoColl->empty() || decodedRdoCollVec.count(rdoColl) ||
339 rdoCollVec.count(rdoColl)) {
340 continue;
341 }
342 ATH_MSG_DEBUG(" Number of RawData in this rdo " << rdoColl->size());
343 for (const TgcRawData* rd : *rdoColl) {
344 selectDecoder(state, *rd, rdoColl);
345 }
346 decodedRdoCollVec.insert(rdoColl);
347 }
348 }
349 // first collect up all the HashIDs in any of the containers
350 std::set<IdentifierHash> hashesInAnyBC;
351 for (unsigned int ibc = 0; ibc < NBC_HIT; ++ibc) {
352
353 uint16_t bcBitMap = 0;
354 if (ibc == 0) {
356 } else if (ibc == 1) {
358 } else if (ibc == 2) {
359 bcBitMap = TgcPrepData::BCBIT_NEXT;
360 }
361
362 for (std::unique_ptr<TgcPrepDataCollection>& bcColl :
363 state.tgcPrepDataCollections[ibc]) {
364 if (!bcColl) {
365 continue;
366 }
367 std::unique_ptr<TgcPrepDataCollection>& allBcColl =
368 state.tgcPrepDataCollections[NBC_HIT][bcColl->identifyHash()];
369 if (!allBcColl) {
370 allBcColl = std::make_unique<TgcPrepDataCollection>(
371 bcColl->identifyHash());
372 allBcColl->setIdentifier(bcColl->identify());
373 }
374 hashesInAnyBC.insert(bcColl->identifyHash());
375 for (const TgcPrepData* prdToUpdate : *bcColl) {
376 auto search_itr = std::find_if(
377 allBcColl->begin(), allBcColl->end(),
378 [prdToUpdate](const TgcPrepData* prd) {
379 return prd->identify() == prdToUpdate->identify();
380 });
381 if (search_itr == allBcColl->end()) {
382 auto allBcPrd = std::make_unique<TgcPrepData>(*prdToUpdate);
383 allBcPrd->setHashAndIndex(allBcColl->identifyHash(),
384 allBcColl->size());
385 allBcPrd->setBcBitMap(bcBitMap);
386 allBcColl->push_back(std::move(allBcPrd));
387 } else {
388 TgcPrepData* allBcPrd = (*search_itr);
389 const uint16_t bcBitMap_current = allBcPrd->getBcBitMap();
391 m_idHelperSvc->toString(allBcPrd->identify())
392 << " Old bitmap " << bcBitMap_current << " adding "
393 << bcBitMap << " to get "
394 << (bcBitMap_current | bcBitMap));
395 allBcPrd->setBcBitMap((bcBitMap_current | bcBitMap));
396 }
397 }
398 }
399 }
400
401 if (!m_xAODKey.empty()) {
402 for (std::unique_ptr<TgcPrepDataCollection>& allBcColl :
404 if (!allBcColl) {
405 continue;
406 }
407 for (const TgcPrepData* allBcPrd : *allBcColl) {
408 xAOD::TgcStrip* tgcStrip =
409 xAODHandle->push_back(std::make_unique<xAOD::TgcStrip>());
410 tgcStrip->setMeasuresPhi(
411 idHelper.isStrip(allBcPrd->identify()));
412 tgcStrip->setGasGap(idHelper.gasGap(allBcPrd->identify()));
413 tgcStrip->setChannelNumber(
414 idHelper.channel(allBcPrd->identify()));
415 tgcStrip->setBcBitMap(allBcPrd->getBcBitMap());
416 tgcStrip->setIdentifier(allBcPrd->identify().get_compact());
419 // rotation from eta -> phi is clockwise --> minus sign in prd
420 // creation
421 const double locPos = (tgcStrip->measuresPhi() ? -1. : 1.) *
422 allBcPrd->localPosition().x();
423 tgcStrip->setMeasurement(
424 m_idHelperSvc->moduleHash(allBcPrd->identify()),
425 xAOD::MeasVector<1>(locPos),
426 xAOD::MeasMatrix<1>(allBcPrd->localCovariance()(0, 0)));
427 }
428 }
429 }
430
431 for (unsigned int k = 0; k < state.tgcPrepDataContainer.size(); ++k) {
433 std::move(state.tgcPrepDataCollections[k])));
434 }
435 for (unsigned int k = 0; k < state.tgcCoinDataContainer.size(); ++k) {
437 std::move(state.tgcCoinDataCollections[k])));
438 }
439 ATH_MSG_DEBUG("Found " << hashesInAnyBC.size()
440 << " hashes that must be added to AllBC container");
441
442 return StatusCode::SUCCESS;
443}
444
446 const TgcRawData& rd,
447 const TgcRdo* rdoColl) const {
448
449 if (!rd.isCoincidence()) {
450 if (!decodeHits(state, rd).isSuccess()) {
451 ATH_MSG_WARNING("Cannot decode TGC Hits");
452 }
453 } else if (rd.isCoincidence() && m_fillCoinData) { // coincidence start
454 StatusCode status = StatusCode::SUCCESS;
455 if (rd.type() == TgcRawData::TYPE_TRACKLET) {
458 status = decodeTracklet(state, rd);
459 } else if (rd.slbType() == TgcRawData::SLB_TYPE_INNER_WIRE ||
461 status = decodeTrackletEIFI(state, rd);
462 }
463 } // rd.rodId()<13 for Run2, rd.rodId()>12 for Run3
464 else if (rd.type() == TgcRawData::TYPE_HIPT &&
465 ((rd.isHipt() && rd.rodId() < 13) || rd.rodId() > 12)) {
466 status = decodeHiPt(state, rd);
467 } else if ((rd.rodId() < 13 && rd.type() == TgcRawData::TYPE_HIPT &&
468 (rd.sector() & 4) != 0) || // Run2
469 (rd.rodId() > 12 &&
470 (rd.type() == TgcRawData::TYPE_INNER_NSW || // Run3
471 rd.type() == TgcRawData::TYPE_INNER_BIS || // Run3
472 rd.type() == TgcRawData::TYPE_INNER_EIFI || // Run3
473 rd.type() == TgcRawData::TYPE_INNER_TMDB))) { // Run3
474 status = decodeInner(state, rd);
475 } else if (rd.type() == TgcRawData::TYPE_SL) {
476 status = decodeSL(state, rd, rdoColl);
477 }
478 if (!status.isSuccess()) {
479 ATH_MSG_WARNING("Cannot decode TGC Coincidences");
480 }
481 }
482}
483
485 State& state, const TgcRawData& rd) const {
486 // The channel hit by hardware-ROD supports only three-bunch readout. Data
487 // of TgcDigit::BC_NEXTNEXT should be skipped in this function.
488 if (rd.bcTag() == TgcDigit::BC_NEXTNEXT) {
489 return StatusCode::SUCCESS;
490 }
491
492 m_nHitRDOs++; // Count the number of input Hit RDOs.
493 bool isConverted{false}, isDuplicated{false}, isInvalid{false};
494
495 ATH_MSG_DEBUG("decodeHits() :" << __LINE__ << " sub=" << rd.subDetectorId()
496 << " rod=" << rd.rodId() << " ssw="
497 << rd.sswId() << " slb=" << rd.slbId()
498 << " bitpos=" << rd.bitpos());
499
500 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
501
502 // select current Hits, =0 for backward compatibility
503 // BC_CURRENT=2, BC_UNDEFINED=0
504 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
506 ? 1
507 : rd.bcTag() - 1;
508
509 // repeat two times for ORed channel
510 for (int iOr = 0; iOr < 2; iOr++) {
511 bool orFlag = false;
512 // check if this channel has ORed partner only when 2nd time
513 if (iOr != 0) {
514 bool o_found = state.cabling->isOredChannel(
515 rd.subDetectorId(), rd.rodId(), rd.sswId(), rd.slbId(),
516 rd.bitpos());
517 // set OR flag
518 if (o_found) {
519 orFlag = true;
520 } else {
521 continue;
522 }
523 }
524
525 // get element ID
526 Identifier elementId{};
527 bool e_found = state.cabling->getElementIDfromReadoutID(
528 elementId, rd.subDetectorId(), rd.rodId(), rd.sswId(), rd.slbId(),
529 rd.bitpos(), orFlag);
530 if (!e_found) {
531 if (!orFlag) {
532 bool show_warning_level = true;
533
534 /* One invalid channel in sector A09:
535 sub=103 rod=9 ssw=6 slb=20 bitpos=151 +offset=0 orFlag=0
536 was always seen in 2008 data, at least run 79772 - 91800.
537 bug #48828 */
538 /* One invalid channel in sector A11:
539 sub=103 rod=11 ssw=2 slb=8 bitpos=41 orFlag=0
540 was seen 5 times in 1,059,867 events of run 159179. */
541 /* EIFI of MC ByteStream without correction issue : bug 57051 */
542 if ((rd.subDetectorId() == 103 && rd.rodId() == 9 &&
543 rd.sswId() == 6 && rd.slbId() == 20 &&
544 rd.bitpos() == 151) ||
545 (rd.subDetectorId() == 103 && rd.rodId() == 11 &&
546 rd.sswId() == 2 && rd.slbId() == 8 && rd.bitpos() == 41) ||
547 (rd.rodId() % 3 == 2 && rd.sswId() == 8)) {
548 show_warning_level =
550 isInvalid = true;
551 }
552 if (msgLvl(show_warning_level ? MSG::WARNING : MSG::DEBUG)) {
553 msg(show_warning_level ? MSG::WARNING : MSG::DEBUG)
554 << "ElementID not found for "
555 << " sub=" << rd.subDetectorId()
556 << " rod=" << rd.rodId() << " ssw=" << rd.sswId()
557 << " slb=" << rd.slbId() << " bitpos=" << rd.bitpos()
558 << " orFlag=" << orFlag << endmsg;
559 }
560 }
561 continue;
562 }
563 const IdentifierHash tgcHashId = m_idHelperSvc->moduleHash(elementId);
564
565 Identifier channelId{};
566 bool c_found = state.cabling->getOfflineIDfromReadoutID(
567 channelId, rd.subDetectorId(), rd.rodId(), rd.sswId(), rd.slbId(),
568 rd.bitpos(), orFlag);
569 if (!c_found) {
570 if (!orFlag) {
572 "OfflineID not found for "
573 << " sub=" << rd.subDetectorId() << " rod=" << rd.rodId()
574 << " ssw=" << rd.sswId() << " slb=" << rd.slbId()
575 << " bitpos=" << rd.bitpos() << " orFlag=" << orFlag);
576 }
577 continue;
578 }
579
580 std::unique_ptr<TgcPrepDataCollection>& collection =
581 state.tgcPrepDataCollections[locId][tgcHashId];
582 if (!collection) {
583 collection = std::make_unique<TgcPrepDataCollection>(tgcHashId);
584 collection->setIdentifier(elementId);
585 }
586 const bool duplicate =
587 std::find_if(collection->begin(), collection->end(),
588 [&channelId](const TgcPrepData* prd) {
589 return prd->identify() == channelId;
590 }) != collection->end();
591 if (duplicate) {
592 isDuplicated = true; // A converted PRD of this RDO is duplicated.
593 continue;
594 }
595
596 const MuonGM::TgcReadoutElement* descriptor =
597 state.muDetMgr->getTgcReadoutElement(channelId);
598 if (!isOfflineIdOKForTgcReadoutElement(descriptor, channelId)) {
600 "decodeHits: MuonGM::TgcReadoutElement is invalid.");
601 continue;
602 }
604 "TGC RDO->PrepRawdata: " << m_idHelperSvc->toString(channelId));
605
606 std::vector<Identifier> identifierList{channelId};
607
608 Amg::Vector3D position = descriptor->channelPos(channelId);
609 Amg::Vector2D hitPos{Amg::Vector2D::Zero()};
610 bool onSurface = descriptor->surface(channelId).globalToLocal(
611 position, position, hitPos);
612 // the globalToLocal should not fail, if it does produce a WARNING
613 if (!onSurface) {
615 "Muon::TgcRdoToPrepDataToolMT::decodeHits Amg::Vector2D* "
616 "hitPos is null.");
617 continue;
618 }
619
620 int gasGap = idHelper.gasGap(channelId);
621 int channel = idHelper.channel(channelId);
622 const double width = !idHelper.isStrip(channelId)
623 ? descriptor->gangRadialLength(gasGap, channel)
624 : descriptor->stripWidth(gasGap, channel);
625
627 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero
628 // are dropped.
629 ATH_MSG_WARNING("decodeHits: width= "
630 << width
631 << " is smaller than s_cutDropPrdsWithZeroWidth= "
633 << m_idHelperSvc->toString(channelId));
634 continue;
635 }
636 double errPos = width / std::sqrt(12.);
637
638 Amg::MatrixX mat(1, 1);
639 mat.setIdentity();
640 mat *= errPos * errPos;
641
642 // add the digit to the collection
643 // new TgcPrepRawData
644 TgcPrepData* newPrepData =
645 new TgcPrepData(channelId, // Readout ID -> Offline ID
646 tgcHashId, // Readout ID -> Element ID -> Hash
647 hitPos, // determined from channelId
648 identifierList, // holds channelId only
649 mat, // determined from channelId
650 descriptor); // determined from channelId
651 newPrepData->setHashAndIndex(collection->identifyHash(),
652 collection->size());
653 collection->push_back(newPrepData);
654 isConverted = true; // This RDO is converted to at least one PRD.
655 }
656
657 if (isConverted) {
658 m_nHitPRDs++; // Count the number of output Hit PRDs.
659 } else if (isDuplicated || isInvalid) {
660 m_nHitRDOs--; // Reduce the number of input RDOs.
661 }
662
663 return StatusCode::SUCCESS;
664}
665
667 State& state, const TgcRawData& rd) const {
668 ++m_nTrackletRDOs; // Count the number of input Tracklet RDOs.
669
670 bool found = false;
671
672 //*** Get OfflineId of pivot plane (TGC3) start ***//
673 Identifier channelIdOut{};
675 channelIdOut, rd.subDetectorId(), rd.rodId(), rd.sswId(), rd.slbId(),
676 rd.subMatrix(), rd.position(), false);
677 if (!found) {
678 ATH_MSG_DEBUG("decodeTracklet: can't get the OfflineIdOut");
679 return StatusCode::SUCCESS;
680 }
681 //*** Get OfflineId of pivot plane (TGC3) end ***//
682
683 //*** Get OfflineId of non-pivot plane (TGC2) start ***//
684 int tmp_slbId{0}, tmp_subMatrix{0}, tmp_position{0};
685 found = getTrackletInfo(rd, tmp_slbId, tmp_subMatrix, tmp_position);
686 if (!found) {
687 return StatusCode::SUCCESS;
688 }
689 Identifier channelIdIn{};
691 channelIdIn, rd.subDetectorId(), rd.rodId(), rd.sswId(), tmp_slbId,
692 tmp_subMatrix, tmp_position, true);
693 if (!found) {
694 ATH_MSG_DEBUG("decodeTracklet: can't get the OfflineIdIn");
695 return StatusCode::SUCCESS;
696 }
697 //*** Get OfflineId of non-pivot plane (TGC2) end ***//
698
699 const IdentifierHash tgcHashId = m_idHelperSvc->moduleHash(channelIdOut);
700
701 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
703 ? 1
704 : rd.bcTag() - 1;
705
706 std::unique_ptr<Muon::TgcCoinDataCollection>& coincollection =
707 state.tgcCoinDataCollections[locId][tgcHashId];
708 if (!coincollection) {
709 coincollection =
710 std::make_unique<Muon::TgcCoinDataCollection>(tgcHashId);
711 coincollection->setIdentifier(m_idHelperSvc->chamberId(channelIdOut));
712 }
713
714 int subMatrix = static_cast<int>(rd.subMatrix());
715 int trackletId = static_cast<int>(2 * rd.slbId() + subMatrix);
716 int delta = static_cast<int>(rd.delta());
717
718 // Check duplicate digits
719 for (const TgcCoinData* tgcCoinData : *coincollection) {
721 tgcCoinData->type() && // coincidence type
722 channelIdOut ==
723 tgcCoinData->identify() && // channelIdOut, identify returns
724 // channelIdOut for Tracklet
725 channelIdIn == tgcCoinData->channelIdIn() && // channelIdIn
726 trackletId == tgcCoinData->trackletId() && // trackletId
727 delta == tgcCoinData->delta() && // delta
728 subMatrix == tgcCoinData->sub()) { // subMatrix
729
730 ATH_MSG_DEBUG("Duplicated TgcCoinData (Tracklet) = "
731 << m_idHelperSvc->toString(channelIdIn));
732 return StatusCode::SUCCESS;
733 }
734 }
735
736 ATH_MSG_DEBUG("TGC RDO->Coindata for LowPT: "
737 << m_idHelperSvc->toString(channelIdOut));
738
739 //*** Get geometry of pivot plane (TGC3) start ***//
740 const MuonGM::TgcReadoutElement* descriptor_o =
741 state.muDetMgr->getTgcReadoutElement(channelIdOut);
742 if (!isOfflineIdOKForTgcReadoutElement(descriptor_o, channelIdOut)) {
743 return StatusCode::SUCCESS;
744 }
745
746 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
747 int gasGap_o = idHelper.gasGap(channelIdOut);
748 int channel_o = idHelper.channel(channelIdOut);
749 double width_o = !idHelper.isStrip(channelIdOut)
750 ? descriptor_o->gangRadialLength(gasGap_o, channel_o)
751 : descriptor_o->stripWidth(gasGap_o, channel_o);
752
753 if (width_o < s_cutDropPrdsWithZeroWidth &&
754 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
755 // dropped.
756 return StatusCode::SUCCESS;
757 }
758
759 Amg::Vector3D position_o = descriptor_o->channelPos(channelIdOut);
760 Amg::Vector2D hitPos_o{Amg::Vector2D::Zero()};
761 bool onSurface_o = descriptor_o->surface(channelIdOut)
762 .globalToLocal(position_o, position_o, hitPos_o);
763 // the globalToLocal should not fail, if it does produce a WARNING
764 if (!onSurface_o) {
766 "Muon::TgcRdoToPrepDataToolMT::decodeTracklet Amg::Vector2D* "
767 "hitPos_o is null.");
768 return StatusCode::SUCCESS;
769 }
770 //*** Get geometry of pivot plane (TGC3) end ***//
771
772 //*** Get geometry of non-pivot plane (TGC2) start ***//
773 const MuonGM::TgcReadoutElement* descriptor_i =
774 state.muDetMgr->getTgcReadoutElement(channelIdIn);
775 if (!isOfflineIdOKForTgcReadoutElement(descriptor_i, channelIdIn)) {
776 return StatusCode::SUCCESS;
777 }
778
779 int gasGap_i = idHelper.gasGap(channelIdIn);
780 int channel_i = idHelper.channel(channelIdIn);
781 double width_i = !idHelper.isStrip(channelIdIn)
782 ? descriptor_i->gangRadialLength(gasGap_i, channel_i)
783 : descriptor_i->stripWidth(gasGap_i, channel_i);
784
785 if (width_i < s_cutDropPrdsWithZeroWidth &&
786 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
787 // dropped.
788 return StatusCode::SUCCESS;
789 }
790
791 Amg::Vector3D position_i = descriptor_i->channelPos(channelIdIn);
792 Amg::Vector2D hitPos_i{Amg::Vector2D::Zero()};
793 bool onSurface_i = descriptor_i->surface(channelIdIn)
794 .globalToLocal(position_i, position_i, hitPos_i);
795 // the globalToLocal should not fail, if it does produce a WARNING
796 if (!onSurface_i) {
798 "Muon::TgcRdoToPrepDataToolMT::decodeTracklet Amg::Vector2D* "
799 "hitPos_i is null.");
800 return StatusCode::SUCCESS;
801 }
802 //*** Get geometry of non-pivot plane (TGC2) end ***//
803 const Amg::Vector2D* hitPosition_o = new Amg::Vector2D(hitPos_o);
804 const Amg::Vector2D* hitPosition_i = new Amg::Vector2D(hitPos_i);
805 // Add the digit to the collection
806 TgcCoinData* newCoinData =
807 new TgcCoinData(channelIdIn, channelIdOut,
808 tgcHashId, // determined from channelIdOut
809 descriptor_i, // determined from channelIdIn
810 descriptor_o, // determined from channelIdOut
812 rd.subDetectorId() == ASIDE, // isAside
813 idHelper.stationPhi(channelIdOut), // phi
814 0, // isInner
815 rd.sswId() == 7 || rd.sswId() == 2, // isForward
816 idHelper.isStrip(channelIdOut), // isStrip
817 trackletId, // trackletId
818 hitPosition_i, // determined from channelIdIn
819 hitPosition_o, // determined from channelIdOut
820 width_i, // determined from channelIdIn
821 width_o, // determined from channelIdOut
822 delta, // delta
823 subMatrix,
824 0); // subMatrix
825 newCoinData->setHashAndIndex(coincollection->identifyHash(),
826 coincollection->size());
827 coincollection->push_back(newCoinData);
828
829 ATH_MSG_DEBUG("coincollection->push_back done (for LowPT)");
830
831 m_nTrackletPRDs++; // Count the number of output Tracklet PRDs.
832
833 return StatusCode::SUCCESS;
834}
835
837 State& state, const TgcRawData& rd) const {
838 // Count the number of input TrackletEIFI RDOs.
840
841 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
842
843 // Determine chamber type
844 bool isStrip = rd.slbType() == TgcRawData::SLB_TYPE_INNER_STRIP;
845 bool isAside = rd.subDetectorId() == ASIDE;
846 // https://twiki.cern.ch/twiki/pub/Main/TgcDocument/EIFI_PSB_SSW_ConnectionTable_v20080808.pdf
847 bool isForward = (rd.slbId() % 2 == 0);
848 // Assuming RXID in the above file is equal to slbId
849 // rodId: 2 5 8 11
850 // slbId FI: 0 2 4 6 8 10 0 2 4 6 8 10 0 2 4 6 8 10 0 2 4
851 // 6 8 10
852 // EI: 1 3 5 7 9 11 1 3 5 XX 9 11 1 3 5 7 9 XX 1 3 5
853 // XX 9 11
854 // slot: 24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
855 // 21 22 23 stationPhi
856 // FI: 24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
857 // 21 22 23 EI: 21 1 2 3 4 5 6 7 8 XX 9 10 11 12 13 14 15 XX
858 // 16 17 18 XX 19 20
859 int slot = ((rd.slbId() / 2) + (rd.rodId() - 2) * 2 + 23) % 24 + 1;
860
861 bool isBackward = false;
862 if (!isForward) { // EI
863 // Special case of EI11
864 if (slot == 15) {
865 isBackward = !isAside;
866 } else if (slot == 16) {
867 isBackward = isAside;
868 } else {
869 // A-side phi0 F: phi1 F: phi2 B
870 // C-side phi0 B: phi1 B: phi2 F
871 if (isAside) {
872 isBackward = (slot % 3 == 2);
873 } else {
874 isBackward = (slot % 3 != 2);
875 }
876 }
877 } else { // FI
878 isBackward = isAside;
879 }
880
881 // Determine bitpos based on wire/strip and subMatrix
882 // Input is chosen so that gasGap is 1 and channel is 4,12,20,28.
883 // One subMatrix covers 8 channels (=BIT_POS_ASD_SIZE/2)
884 uint16_t bitpos = 0;
885 if (!isStrip) { // Wire
886 // For wires, D-Input is gasGap=1
887
888 int tmpsubMatrix = static_cast<int>(rd.subMatrix());
889 if (!isForward) { // If an edge channel of EI fires, subMatrix of the
890 // tracklet can be greater than one of the hit
891 // channel.
892 if (tmpsubMatrix == 3) {
893 if (slot == 1 || slot == 3 || slot == 4 || slot == 5 ||
894 slot == 6 || slot == 7 || slot == 8 || slot == 10 ||
895 slot == 11 || slot == 13 || slot == 18 || slot == 19 ||
896 slot == 20) {
897 // These slots have only 24 wire channels (=3 submatrixes)
898 tmpsubMatrix = 2;
899 }
900 } else if (tmpsubMatrix == 2) {
901 if (slot == 2 || slot == 12 || slot == 14 || slot == 15 ||
902 slot == 16 || slot == 22 || slot == 23 || slot == 24) {
903 // These slots have only 16 wire channels (=2 submatrixes)
904 tmpsubMatrix = 1;
905 }
906 }
907 }
908
910 BIT_POS_ASD_SIZE / 4 * (tmpsubMatrix * 2 + 1);
911 } else { // Strip
912 if (isBackward) {
913 // For Backward chambers, B-Input is gasGap 1
915 (isAside ? 1 : 0) +
916 BIT_POS_ASD_SIZE / 4 * (rd.subMatrix() * 2 + 1);
917 } else {
918 // For Forward chambers, A-Input is gasGap 1
920 (isAside ? 0 : 1) +
921 BIT_POS_ASD_SIZE / 4 * (rd.subMatrix() * 2 + 1);
922 }
923 }
924
925 // Retrieve OfflineID from ReadoutID
926 Identifier channelIdIn;
927 bool o_found = state.cabling->getOfflineIDfromReadoutID(
928 channelIdIn, rd.subDetectorId(), rd.rodId(), rd.sswId(), rd.slbId(),
929 bitpos, false /*orflag*/);
930 if (!o_found) {
932 "Muon::TgcRdoToPrepDataToolMT::decodeTrackletEIFI OfflineID not "
933 "found for "
934 << " subDetectorId=" << rd.subDetectorId() << " rodId="
935 << rd.rodId() << " sswId=" << rd.sswId() << " slbId=" << rd.slbId()
936 << " slbType=" << rd.slbType() << " subMatrix=" << rd.subMatrix()
937 << " bitpos=" << bitpos << " isStrip=" << isStrip
938 << " isAside=" << isAside << " isForward=" << isForward
939 << " slot=" << slot << " isBackward=" << isBackward);
940 return StatusCode::SUCCESS;
941 }
942
943 // Retrieve Hash from ElementID
944 const IdentifierHash tgcHashId = m_idHelperSvc->moduleHash(channelIdIn);
945 // Index is determined based on bcTag.
946 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
948 ? 1
949 : rd.bcTag() - 1;
950
951 std::unique_ptr<Muon::TgcCoinDataCollection>& coincollection =
952 state.tgcCoinDataCollections[locId][tgcHashId];
953 if (!coincollection) {
954 coincollection =
955 std::make_unique<Muon::TgcCoinDataCollection>(tgcHashId);
956 coincollection->setIdentifier(m_idHelperSvc->chamberId(channelIdIn));
957 }
958
959 // Check duplicate digits
960 for (const TgcCoinData* tgcCoinData : *coincollection) {
962 tgcCoinData->type() && // coincidence type
963 channelIdIn == tgcCoinData->channelIdIn() && // channelIdIn
964 static_cast<int>(rd.subMatrix()) == tgcCoinData->sub()) { // sub
965 ATH_MSG_DEBUG("Duplicated TgcCoinData (TrackletEIFI) = "
966 << m_idHelperSvc->toString(channelIdIn));
967 return StatusCode::SUCCESS;
968 }
969 }
970 // Get MuonGM::TgcReadoutElement from channelIdIn
971 const MuonGM::TgcReadoutElement* descriptor =
972 state.muDetMgr->getTgcReadoutElement(channelIdIn);
973 if (!isOfflineIdOKForTgcReadoutElement(descriptor, channelIdIn)) {
975 "Muon::TgcRdoToPrepDataToolMT::decodeTrackletEIFI descriptor "
976 "doesn't contain "
977 << m_idHelperSvc->toString(channelIdIn));
978 return StatusCode::SUCCESS;
979 }
980
981 // Get Amg::Vector2D from channelIdIn //here I am
982 Amg::Vector3D position = descriptor->channelPos(channelIdIn);
983 Amg::Vector2D hitPos{Amg::Vector2D::Zero()};
984 bool onSurface = descriptor->surface(channelIdIn)
985 .globalToLocal(position, position, hitPos);
986 // the globalToLocal should not fail, if it does produce a WARNING
987 if (!onSurface) {
989 "Muon::TgcRdoToPrepDataToolMT::decodeTrackletEIFI Amg::Vector2D* "
990 "hitPos is null.");
991 return StatusCode::SUCCESS;
992 }
993
994 // Get width from channelIdIn, one subMatrix covers 8 channels per gasGap
995 int gasGap = idHelper.gasGap(channelIdIn); // 1
996 int channel = idHelper.channel(channelIdIn); // 4, 12, 20, 28
997 double width{0};
998 if (isStrip) { // Strip
999 double localZ = (descriptor->transform(channelIdIn).inverse() *
1000 descriptor->channelPos(channelIdIn))
1001 .z();
1002 double stripMaxX =
1003 descriptor->stripHighEdgeLocX(gasGap, channel + 4, localZ);
1004 double stripMinX =
1005 descriptor->stripLowEdgeLocX(gasGap, channel - 3, localZ);
1006 width = std::abs(stripMaxX - stripMinX);
1007 } else { // Wire
1008 int positiveOffset = +4;
1009 if (isForward && (slot % 3 == 2) && channel == 28) {
1010 positiveOffset = +2; // T10S has only 30 channels.
1011 }
1012 double gangMaxZ =
1013 descriptor->gangLongWidth(gasGap, channel + positiveOffset);
1014 double gangMinZ = descriptor->gangShortWidth(gasGap, channel - 3);
1015 width = std::abs(gangMaxZ - gangMinZ);
1016 }
1017
1018 const Amg::Vector2D* hitPosition = new Amg::Vector2D(hitPos);
1019 // Add the digit to the collection
1020 TgcCoinData* newCoinData =
1021 new TgcCoinData(channelIdIn,
1022 tgcHashId, // determined from channelIdIn
1023 descriptor, // determined from channelIdIn
1025 m_idHelperSvc->tgcIdHelper().stationPhi(channelIdIn),
1026 isForward, isStrip,
1027 hitPosition, // determined from channelIdIn
1028 width, // determined from channelIdIn
1029 static_cast<int>(rd.subMatrix())); // subMatrix
1030 newCoinData->setHashAndIndex(coincollection->identifyHash(),
1031 coincollection->size());
1032 coincollection->push_back(newCoinData);
1033
1034 // Count the number of output Tracklet EIFI PRDs.
1036 return StatusCode::SUCCESS;
1037}
1038
1040 State& state, const TgcRawData& rd0) const {
1041 m_nHiPtRDOs++; // Count the number of input HiPt RDOs.
1042
1043 // conversion for Run3
1044 uint16_t tmprodId{}, tmpsector{};
1045 convertToRun2(rd0, tmprodId, tmpsector);
1046 const TgcRawData rd(rd0.bcTag(), rd0.subDetectorId(), tmprodId, rd0.l1Id(),
1047 rd0.bcId(), rd0.isStrip(), rd0.isForward(), tmpsector,
1048 rd0.chip(), rd0.index(), rd0.isHipt(), rd0.hitId(),
1049 rd0.hsub(), rd0.delta(), rd0.inner());
1050
1051 // Protection against invalid subDetectorId and isForward
1052 if ((rd.subDetectorId() != ASIDE && rd.subDetectorId() != CSIDE)) {
1054 "TgcRdoToPrepDataToolMT::decodeHiPt::Unknown subDetectorId!!");
1055 return StatusCode::SUCCESS;
1056 }
1057
1058 // Protection against invalid hitId
1059 if (rd.hitId() == 0) {
1061 "Invalid hitId_rdo_hipt, hitId == 0!! skip to convert this RDO to "
1062 "PRD");
1063 return StatusCode::SUCCESS;
1064 }
1065 int slbsubMatrix = 0;
1066 bool isBackward = isBackwardBW(rd); // Backward or Forward
1067 int deltaBeforeConvert = getDeltaBeforeConvert(rd);
1068
1069 bool found = false;
1070
1071 Identifier channelIdOut_tmp{};
1072 std::array<Identifier, 2> channelIdOut{};
1073 std::array<int, 2> bitpos_o{}, slbchannel_o{};
1074 int sswId_o{0}, sbLoc_o{0}, slbId_o{0};
1075
1076 Identifier channelIdIn_tmp{};
1077 std::array<Identifier, 4> channelIdIn{};
1078 std::array<int, 4> bitpos_i{}, slbchannel_i{};
1079 int sswId_i{0}, sbLoc_i{0};
1080
1081 std::array<int, 4> slbId_in{}, sbLoc_in{}; // only used for wire
1082
1083 std::array<int, 4> gasGap_i{}, channel_i{};
1084 double width_i{0.}, hit_position_i{0};
1085 Amg::Vector2D tmp_hitPos_i{Amg::Vector2D::Zero()};
1086
1087 std::array<int, 2> gasGap_o{}, channel_o{};
1088 double width_o{0.}, hit_position_o{0.};
1089 Amg::Vector2D tmp_hitPos_o{Amg::Vector2D::Zero()};
1090
1091 const MuonGM::TgcReadoutElement* descriptor_ii = nullptr;
1092 const MuonGM::TgcReadoutElement* descriptor_oo = nullptr;
1093
1094 //*** TGC3 start ***//
1095 // RDOHighPtID --> (Sim)HighPtID --> OfflineID --> ReadoutID --> getSLBID
1096 found = getHiPtIds(state, rd, sswId_o, sbLoc_o, slbId_o);
1097 if (!found) {
1098 return StatusCode::SUCCESS;
1099 }
1100
1101 // get the OfflineID of cernter of ROI of TGC3
1102 if (!rd.isStrip()) { // wire
1103 getBitPosOutWire(rd, slbsubMatrix, bitpos_o);
1104 } else { // strip
1105 getBitPosOutStrip(rd, slbsubMatrix, bitpos_o);
1106 }
1107 for (int i = 0; i < 2; i++) {
1108 found = state.cabling->getOfflineIDfromReadoutID(
1109 channelIdOut[i], rd.subDetectorId(), rd.rodId(), sswId_o, sbLoc_o,
1110 bitpos_o[i]);
1111 if (!found) {
1112 ATH_MSG_DEBUG("Failed to get OfflineID from ReadoutID for Pivot "
1113 << (rd.isStrip() ? "Strip" : "Wire") << ".");
1114 return StatusCode::SUCCESS;
1115 }
1116 }
1117
1118 //}
1119 //*** TGC3 end ***//
1120
1121 //*** TGC1 start ***//
1122 // get the OfflineID of cernter of ROI of TGC1
1123 if (!rd.isStrip()) { // wire
1124 getBitPosInWire(rd, deltaBeforeConvert, bitpos_i, slbchannel_i,
1125 slbId_in, sbLoc_in, sswId_i, bitpos_o, slbchannel_o,
1126 slbId_o);
1127 } else { // strip
1128 getBitPosInStrip(rd, deltaBeforeConvert, bitpos_i, slbchannel_i,
1129 sbLoc_i, sswId_i, bitpos_o, slbchannel_o);
1130 }
1131 for (int i = 0; i < 4; i++) {
1132 found = state.cabling->getOfflineIDfromReadoutID(
1133 channelIdIn[i], rd.subDetectorId(), rd.rodId(), sswId_i,
1134 rd.isStrip() ? sbLoc_i : sbLoc_in[i], bitpos_i[i]);
1135 if (!found) {
1136 ATH_MSG_DEBUG("Failed to get OfflineID from ReadoutID for Pivot "
1137 << (rd.isStrip() ? "Strip" : "Wire") << ".");
1138 return StatusCode::SUCCESS;
1139 }
1140 }
1141 //}
1142 //*** TGC1 end ***//
1143
1144 ATH_MSG_DEBUG("TGC RDO->Coindata for HIPT: "
1145 << m_idHelperSvc->toString(channelIdOut[1]));
1146
1147 const IdentifierHash tgcHashId = m_idHelperSvc->moduleHash(channelIdOut[1]);
1148
1149 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
1151 ? 1
1152 : rd.bcTag() - 1;
1153
1154 std::unique_ptr<Muon::TgcCoinDataCollection>& coincollection =
1155 state.tgcCoinDataCollections[locId][tgcHashId];
1156 if (!coincollection) {
1157 coincollection =
1158 std::make_unique<Muon::TgcCoinDataCollection>(tgcHashId);
1159 coincollection->setIdentifier(
1160 m_idHelperSvc->chamberId(channelIdOut[1]));
1161 }
1162
1163 //*** TGC3 start ***//
1164 // Get geometry of pivot plane
1165 std::array<const MuonGM::TgcReadoutElement*, 2> descriptor_o{
1166 state.muDetMgr->getTgcReadoutElement(channelIdOut[0]),
1167 state.muDetMgr->getTgcReadoutElement(channelIdOut[1])};
1168 for (int i = 0; i < 2; i++) {
1169 if (!isOfflineIdOKForTgcReadoutElement(descriptor_o[i],
1170 channelIdOut[i])) {
1171 return StatusCode::SUCCESS;
1172 }
1173 }
1174
1175 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
1176 for (int i = 0; i < 2; i++) {
1177 gasGap_o[i] = idHelper.gasGap(channelIdOut[i]);
1178 channel_o[i] = idHelper.channel(channelIdOut[i]);
1179 }
1180
1181 if (!rd.isStrip()) { // wire
1182 found = getPosAndIdWireOut(descriptor_o, channelIdOut, gasGap_o,
1183 channel_o, width_o, hit_position_o,
1184 tmp_hitPos_o, channelIdOut_tmp);
1185 } else { // strip
1186 found = getPosAndIdStripOut(descriptor_o, channelIdOut, gasGap_o,
1187 channel_o, width_o, hit_position_o,
1188 tmp_hitPos_o, channelIdOut_tmp, isBackward,
1189 rd.subDetectorId() == ASIDE);
1190 }
1191 if (!found) {
1192 return StatusCode::SUCCESS;
1193 }
1194 if (width_o < s_cutDropPrdsWithZeroWidth &&
1195 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
1196 // dropped.
1197 return StatusCode::SUCCESS;
1198 }
1199
1200 descriptor_oo = state.muDetMgr->getTgcReadoutElement(channelIdOut_tmp);
1201 if (!isOfflineIdOKForTgcReadoutElement(descriptor_oo, channelIdOut_tmp)) {
1202 return StatusCode::SUCCESS;
1203 }
1204 //}
1205 //*** TGC3 end ***//
1206
1207 //*** TGC1 start ***//
1208 // Get geometry of non-pivot plane
1209 std::array<const MuonGM::TgcReadoutElement*, 4> descriptor_i{
1210 state.muDetMgr->getTgcReadoutElement(channelIdIn[0]),
1211 state.muDetMgr->getTgcReadoutElement(channelIdIn[1]),
1212 state.muDetMgr->getTgcReadoutElement(channelIdIn[2]),
1213 state.muDetMgr->getTgcReadoutElement(channelIdIn[3])};
1214 for (int i = 0; i < 4; i++) {
1215 if (!isOfflineIdOKForTgcReadoutElement(descriptor_i[i],
1216 channelIdIn[i])) {
1217 return StatusCode::SUCCESS;
1218 }
1219 }
1220 for (int i = 0; i < 4; i++) {
1221 gasGap_i[i] = idHelper.gasGap(channelIdIn[i]);
1222 channel_i[i] = idHelper.channel(channelIdIn[i]);
1223 }
1224
1225 if (!rd.isStrip()) { // WIRE
1226 found = getPosAndIdWireIn(descriptor_i, channelIdIn, gasGap_i,
1227 channel_i, width_i, hit_position_i,
1228 tmp_hitPos_i, channelIdIn_tmp);
1229 } else { // STRIP
1230 found = getPosAndIdStripIn(descriptor_i, channelIdIn, gasGap_i,
1231 channel_i, width_i, hit_position_i,
1232 tmp_hitPos_i, channelIdIn_tmp, isBackward,
1233 (rd.subDetectorId() == ASIDE));
1234 }
1235 if (!found) {
1236 return StatusCode::SUCCESS;
1237 }
1238 if (width_i < s_cutDropPrdsWithZeroWidth &&
1239 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
1240 // dropped.
1241 return StatusCode::SUCCESS;
1242 }
1243
1244 descriptor_ii = state.muDetMgr->getTgcReadoutElement(channelIdIn_tmp);
1245 if (!isOfflineIdOKForTgcReadoutElement(descriptor_ii, channelIdIn_tmp)) {
1246 return StatusCode::SUCCESS;
1247 }
1248 //}
1249 //*** TGC1 end ***//
1250
1251 int trackletId = 2 * sbLoc_o + slbsubMatrix;
1252 int delta = static_cast<int>(rd.delta());
1253 int hsub = static_cast<int>(rd.hsub());
1254 int inner = static_cast<int>(rd.inner());
1255
1256 // check duplicate digits
1257 for (const TgcCoinData* tgcCoinData : *coincollection) {
1259 tgcCoinData->type()) && // Coincidence type
1260 (channelIdOut_tmp ==
1261 tgcCoinData->identify()) && // channelIdOut, identify returns
1262 // channelIdOut for HiPt
1263 (channelIdIn_tmp == tgcCoinData->channelIdIn()) && // channelIdIn
1264 (trackletId == tgcCoinData->trackletId()) && // trackletId
1265 (delta == tgcCoinData->delta()) && // delta
1266 (hsub == tgcCoinData->sub()) && // hsub
1267 (inner == tgcCoinData->inner())) {
1268 if (38 <= trackletId && trackletId <= 41) {
1269 // This drop is most probably due to the fix of the HiPt Endcap
1270 // Strip Board bug.
1271 m_nHiPtRDOs--; // Reduce the number of input RDOs.
1272 }
1273 ATH_MSG_DEBUG("Duplicated TgcCoinData (HiPt) = "
1274 << m_idHelperSvc->toString(channelIdOut_tmp));
1275 return StatusCode::SUCCESS;
1276 }
1277 }
1278
1279 auto hitPos_o = std::make_unique<Amg::Vector2D>(tmp_hitPos_o);
1280 auto hitPos_i = std::make_unique<Amg::Vector2D>(tmp_hitPos_i);
1281
1282 TgcCoinData* newCoinData = new TgcCoinData(
1283 channelIdIn_tmp, channelIdOut_tmp,
1284 tgcHashId, // determined from channelIdOut[1]
1285 descriptor_ii, // determined from channelIdIn_tmp
1286 descriptor_oo, // determined from channelIdOut_tmp
1287 TgcCoinData::TYPE_HIPT, // Coincidence type
1288 rd.subDetectorId() == ASIDE, // isAside
1289 idHelper.stationPhi(channelIdOut_tmp), // phi
1290 0, // isInner
1291 rd.isForward(), // isForward
1292 rd.isStrip(), // isStrip
1293 trackletId, // trackletId
1294 hitPos_i.release(), hitPos_o.release(), width_i, width_o,
1295 delta, // delta
1296 hsub, // hsub
1297 inner);
1298 // add the digit to the collection
1299 newCoinData->setHashAndIndex(coincollection->identifyHash(),
1300 coincollection->size());
1301 coincollection->push_back(newCoinData);
1302
1303 ATH_MSG_DEBUG("coincollection->push_back done (for HIPT)");
1304
1305 m_nHiPtPRDs++; // Count the number of output HiPt PRDs.
1306
1307 return StatusCode::SUCCESS;
1308}
1309
1311 State& state, const TgcRawData& rd) const {
1312 m_nHiPtRDOs++; // Count the number of input HiPt RDOs.
1313
1314
1315 int subDetectorId = rd.subDetectorId();
1316 // Protection against invalid subDetectorId and isForward
1317 if (subDetectorId != ASIDE && subDetectorId != CSIDE) {
1319 "TgcRdoToPrepDataToolMT::decodeHiPt::Unknown subDetectorId!!");
1320 return StatusCode::SUCCESS;
1321 }
1322
1323 bool isInner = ((rd.sector() & 4) != 0); // Inner flag for EIFI and Tilecal
1324
1325 Identifier channelIdIn{};
1326 Identifier channelIdOut{};
1327 int sswId_o = 9;
1328 int sbLoc_o = rd.sector() & 3;
1329 int inner = rd.inner();
1330 bool isStrip = rd.isStrip();
1331
1332 int phi = 0;
1333 bool isAside = false;
1334 bool isEndcap = false;
1335 if (rd.rodId() < 13) { // Run2
1336 state.cabling->getSLIDfromReadoutID(phi, isAside, isEndcap,
1337 subDetectorId, rd.rodId(),
1338 sswId_o, sbLoc_o);
1339 } else { // Run3
1340 sbLoc_o = rd.sector();
1342 phi, isAside, subDetectorId, rd.rodId(), sbLoc_o, rd.isForward());
1343 isEndcap = !rd.isForward();
1344 if (rd.type() == TgcRawData::TYPE_INNER_NSW) {
1345 isInner = true;
1346 isStrip = false;
1349 (rd.nswdtheta()
1351 (rd.nswphires()
1353 (rd.nswlowres()
1362 } else if (rd.type() == TgcRawData::TYPE_INNER_BIS) {
1363 isInner = true;
1364 isStrip = true;
1365 inner =
1376 } else if (rd.type() == TgcRawData::TYPE_INNER_EIFI) {
1377 isInner = false;
1378 isStrip = false;
1382 } else if (rd.type() == TgcRawData::TYPE_INNER_TMDB) {
1383 isInner = false;
1384 isStrip = true;
1385 inner =
1386 (rd.tmdbmod()
1389 }
1390 }
1391
1392 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
1394 ? 1
1395 : rd.bcTag() - 1;
1396
1397 auto hitPos_o = std::make_unique<Amg::Vector2D>(Amg::Vector2D::Zero());
1398 auto hitPos_i = std::make_unique<Amg::Vector2D>(Amg::Vector2D::Zero());
1399
1400 const MuonGM::TgcReadoutElement* descriptor_ii = nullptr;
1401 const MuonGM::TgcReadoutElement* descriptor_oo = nullptr;
1402
1403 std::string stationName = "T3E";
1404 int stationEta = isAside ? 1 : -1;
1405 int stationPhi = phi;
1406 bool isValid{false};
1407 Identifier elementId = m_idHelperSvc->tgcIdHelper().elementID(
1408 stationName, stationEta, stationPhi, isValid);
1409 const IdentifierHash tgcHashId = m_idHelperSvc->moduleHash(elementId);
1410
1411 std::unique_ptr<Muon::TgcCoinDataCollection>& coincollection =
1412 state.tgcCoinDataCollections[locId][tgcHashId];
1413 if (!coincollection) {
1414 coincollection =
1415 std::make_unique<Muon::TgcCoinDataCollection>(tgcHashId);
1416 coincollection->setIdentifier(elementId);
1417 }
1418
1419 ATH_MSG_DEBUG("Inner Data Word, phi: "
1420 << phi << " isAside: " << isAside << " isEndcap: " << isEndcap
1421 << " subDetectorId: " << subDetectorId
1422 << " isStrip: " << rd.isStrip() << " rodId: " << rd.rodId()
1423 << " slbId: " << sbLoc_o << " inner:" << rd.inner());
1424
1425 TgcCoinData* newCoinData = new TgcCoinData(
1426 channelIdIn, // empty
1427 channelIdOut, // empty
1428 tgcHashId, // determined from channelIdOut[1]
1429 descriptor_ii, // determined from channelIdIn_tmp
1430 descriptor_oo, // determined from channelIdOut_tmp
1431 (rd.rodId() < 13)
1433 : (TgcCoinData::TYPE_UNKNOWN), // Coincidence type: rd.rodId()<13
1434 // for Run2, rd.rodId()>12 for Run3
1435 isAside, // isAside
1436 phi, // phi
1437 isInner, // Selection for NSW/BIS/EIFI/TMDB
1438 !isEndcap, // isForward
1439 isStrip, // Selection for NSW/BIS/EIFI/TMDB
1440 0, // trackletId
1441 hitPos_i.release(), hitPos_o.release(),
1442 0., // width_i,
1443 0., // width_o,
1444 0, // delta,
1445 0, // hsub,
1446 inner);
1447 // add the digit to the collection
1448 newCoinData->setHashAndIndex(coincollection->identifyHash(),
1449 coincollection->size());
1450 coincollection->push_back(newCoinData);
1451
1452 ATH_MSG_DEBUG("coincollection->push_back done (for Inner)");
1453
1454 m_nHiPtPRDs++; // Count the number of output HiPt PRDs.
1455
1456 return StatusCode::SUCCESS;
1457}
1458
1460 const TgcRawData& rd0,
1461 const TgcRdo* rdoColl) const {
1462 m_nSLRDOs++; // Count the number of input SL RDOs.
1463
1464 // conversion for Run3
1465 uint16_t tmprodId, tmpsector;
1466 convertToRun2(rd0, tmprodId, tmpsector);
1467 const TgcRawData rd(rd0.bcTag(), rd0.subDetectorId(), tmprodId, rd0.l1Id(),
1468 rd0.bcId(), rd0.isForward(), tmpsector, rd0.innerflag(),
1469 rd0.coinflag(), rd0.isMuplus(), rd0.threshold(),
1470 rd0.roi());
1471
1472 // Protection against invalid subDetectorId
1473 if (rd.subDetectorId() != ASIDE && rd.subDetectorId() != CSIDE) {
1475 "TgcRdoToPrepDataToolMT::decodeSL::Unknown subDetectorId!!");
1476 return StatusCode::SUCCESS;
1477 }
1478
1479 bool found = false;
1480
1481 std::array<Identifier, 3> channelId_wire{};
1482 int index_w{0}, chip_w{0}, hitId_w{0}, sub_w{0}, sswId_w{0}, sbLoc_w{0},
1483 subMatrix_w{0};
1484 std::array<int, 3> bitpos_w{};
1485
1486 //*** get OfflineID, center of ROI of R (wire) ***//
1487 found = getSLIds(state, false, rd, channelId_wire, index_w, chip_w, hitId_w, sub_w,
1488 sswId_w, sbLoc_w, subMatrix_w, bitpos_w);
1489 if (!found) {
1490 return StatusCode::SUCCESS;
1491 }
1492
1493 std::array<Identifier, 3> channelId_strip{};
1494 int index_s{0}, chip_s{0}, hitId_s{0}, sub_s{0}, sswId_s{0}, sbLoc_s{0},
1495 subMatrix_s{0};
1496 std::array<int, 3> bitpos_s{};
1497
1498 //*** get OfflineID, center of ROI of phi (strip) ***//
1499 found = getSLIds(state, true, rd, channelId_strip, index_s, chip_s, hitId_s, sub_s,
1500 sswId_s, sbLoc_s, subMatrix_s, bitpos_s,
1501 isIncludedInChamberBoundary(rd), rdoColl, index_w, chip_w,
1502 hitId_w, sub_w);
1503 if (!found) {
1504 return StatusCode::SUCCESS;
1505 }
1506
1507 ATH_MSG_DEBUG("TGC RDO->TgcCoindata(SL): "
1508 << m_idHelperSvc->toString(channelId_wire[1]));
1509
1510 const IdentifierHash tgcHashId =
1511 m_idHelperSvc->moduleHash(channelId_wire[1]);
1512
1513 int locId = (rd.bcTag() == TgcDigit::BC_CURRENT ||
1515 ? 1
1516 : rd.bcTag() - 1;
1517
1518 std::unique_ptr<Muon::TgcCoinDataCollection>& coincollection =
1519 state.tgcCoinDataCollections[locId][tgcHashId];
1520 if (!coincollection) {
1521 coincollection =
1522 std::make_unique<Muon::TgcCoinDataCollection>(tgcHashId);
1523 coincollection->setIdentifier(
1524 m_idHelperSvc->chamberId(channelId_wire[1]));
1525 }
1526
1527 int trackletId = 2 * sbLoc_w + subMatrix_w;
1528 int trackletIdStrip = 2 * sbLoc_s + subMatrix_s;
1529 int roi = static_cast<int>(rd.roi());
1530 int pt = static_cast<int>(rd.threshold());
1531 if (rd0.rodId() > 12) { // Run3: pT 4 bit, CoinFlag 3 bit, InnerFlag 4 bit
1532 pt += (static_cast<int>(rd.coinflag()) << 4);
1533 pt += (static_cast<int>(rd.innerflag()) << 7);
1534 }
1535 bool veto = rd.isVeto();
1536 bool isPositiveDeltaR =
1537 rd.isMuplus(); // Current SL sets isMuplus flag based on sign of
1538 // deltaR. Postive deltaR gives isMuplus=true.
1539 // check duplicate digits
1540 for (const TgcCoinData* tgcCoinData : *coincollection) {
1541 if (TgcCoinData::TYPE_SL == tgcCoinData->type() &&
1542 channelId_wire[2] == tgcCoinData->identify() &&
1543 trackletId == tgcCoinData->trackletId() &&
1544 trackletIdStrip == tgcCoinData->trackletIdStrip() &&
1545 roi == tgcCoinData->roi() && pt == tgcCoinData->pt() &&
1546 veto == tgcCoinData->veto() &&
1547 isPositiveDeltaR == tgcCoinData->isPositiveDeltaR()) {
1548 ATH_MSG_DEBUG("Duplicated TgcCoinData (SL) = "
1549 << m_idHelperSvc->toString(channelId_wire[2]));
1550 return StatusCode::SUCCESS;
1551 }
1552 }
1553
1554 //*** R (wire) start ***//
1555 double width_w{0.}, tmp_r{0.}, tmp_wire_z{0.};
1556 found = getSLWireGeometry(channelId_wire, width_w, tmp_r, tmp_wire_z);
1557 if (!found) {
1558 return StatusCode::SUCCESS;
1559 }
1560 if (width_w < s_cutDropPrdsWithZeroWidth &&
1561 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
1562 // dropped.
1563 return StatusCode::SUCCESS;
1564 }
1565
1566 double tmp_eta = 0.;
1567 bool isGoodEta = getEtafromRZ(tmp_r, tmp_wire_z, tmp_eta);
1568 if (!isGoodEta) {
1570 "Conversion from r and z to eta by "
1571 "Muon::TgcRdoToPrepDataToolMT::getEtafromRZ failed.");
1572 return StatusCode::SUCCESS;
1573 }
1574 if (tmp_wire_z < 0.) {
1575 tmp_eta *= -1.;
1576 }
1577 //*** R (wire) end ***//
1578
1579 //*** Phi (strip) start ***//
1580 double width_s{0.}, tmp_phi{0.};
1581 found = getSLStripGeometry(channelId_strip, isBackwardBW(rd),
1582 (rd.subDetectorId() == ASIDE), width_s, tmp_phi);
1583 if (!found) {
1584 return StatusCode::SUCCESS;
1585 }
1586 if (width_s < s_cutDropPrdsWithZeroWidth &&
1587 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
1588 // dropped.
1589 return StatusCode::SUCCESS;
1590 }
1591 //*** Phi (strip) end ***//
1592 const MuonGM::TgcReadoutElement* descriptor_w2 =
1593 state.muDetMgr->getTgcReadoutElement(channelId_wire[2]);
1594 if (!isOfflineIdOKForTgcReadoutElement(descriptor_w2, channelId_wire[2])) {
1595 return StatusCode::SUCCESS;
1596 }
1597
1598 Amg::Vector3D tmp_gp(tmp_r * std::cos(tmp_phi), tmp_r * std::sin(tmp_phi),
1599 tmp_wire_z);
1600 Amg::Vector2D tmp_hitPos{Amg::Vector2D::Zero()};
1601 bool onSurface = descriptor_w2->surface(channelId_wire[2])
1602 .globalToLocal(tmp_gp, tmp_gp, tmp_hitPos);
1603 // If TGC A-lines with rotations are used, the z-coordinate of a chamber
1604 // depends on position. In this case, the global to local conversion fails.
1605 // Obtain the local position in a different way.
1606 const Amg::Vector2D* hitPos = new Amg::Vector2D(!onSurface ? tmp_hitPos
1607 : getSLLocalPosition(descriptor_w2, channelId_wire[2],
1608 tmp_eta, tmp_phi));
1609
1610 Amg::MatrixX mat(2, 2);
1611 mat.setIdentity();
1612 mat(0, 0) = width_w;
1613 mat(1, 1) = width_s;
1614 const Amg::MatrixX* errMat = new Amg::MatrixX(std::move(mat));
1615
1616 // new TgcCoinData
1617 TgcCoinData* newCoinData = new TgcCoinData(
1618 channelId_wire[2],
1619 tgcHashId, // determined from channelId_wire[1]
1620 descriptor_w2, // determined from channelId_wire[2]
1621 TgcCoinData::TYPE_SL, // Coincidence type
1622 rd.subDetectorId() == ASIDE, // isAside
1623 m_idHelperSvc->tgcIdHelper().stationPhi(channelId_wire[2]), // phi
1624 rd.isForward(), // isForward
1625 trackletId, // trackletId
1626 trackletIdStrip, // trackletIdStrip
1627 hitPos, errMat,
1628 roi, // roi from RDO
1629 pt, // threshold from RDO
1630 veto, // veto flag from RDO
1631 isPositiveDeltaR); // isMuplus from RDO
1632
1633 // add the digit to the collection
1634 newCoinData->setHashAndIndex(coincollection->identifyHash(),
1635 coincollection->size());
1636 coincollection->push_back(newCoinData);
1637 ATH_MSG_DEBUG("coincollection->push_back done (for SL)");
1638
1639 m_nSLPRDs++; // Count the number of output SL PRDs.
1640 return StatusCode::SUCCESS;
1641}
1642
1644 TgcRawData::SlbType slbType) {
1645 int bitpos = -BIT_POS_INPUT_SIZE + 1;
1646 if (slbType == TgcRawData::SLB_TYPE_TRIPLET_WIRE) {
1647 if (channel < 0 || channel >= WT_MAP_SIZE) {
1648 return -1; // Invalid channel
1649 }
1650
1651 if (channel % 3 == 0) {
1652 bitpos += BIT_POS_C_INPUT_ORIGIN; // C-Input
1653 } else if (channel % 3 == 1) {
1654 bitpos += BIT_POS_B_INPUT_ORIGIN; // B-Input
1655 } else {
1656 bitpos += BIT_POS_A_INPUT_ORIGIN; // A-Input
1657 }
1658 return bitpos + channel / 3;
1659 } else if (slbType == TgcRawData::SLB_TYPE_TRIPLET_STRIP ||
1661 if (channel < 0 || channel >= ST_MAP_SIZE) {
1662 return -1; // Invalid channel, SD_MAP_SIZE is equal to ST_MAP_SIZE.
1663 }
1664
1665 if (channel % 2 == 0) {
1666 bitpos += BIT_POS_B_INPUT_ORIGIN; // B-Input
1667 } else {
1668 bitpos += BIT_POS_A_INPUT_ORIGIN; // A-Input
1669 }
1670 return bitpos + channel / 2;
1671 } else if (slbType == TgcRawData::SLB_TYPE_DOUBLET_WIRE) {
1672 if (channel < 0 || channel >= WD_MAP_SIZE) {
1673 return -1; // Invalid channel
1674 }
1675
1676 if (channel % 2 == 0) {
1677 bitpos += BIT_POS_B_INPUT_ORIGIN; // B-Input
1678 } else {
1679 bitpos += BIT_POS_A_INPUT_ORIGIN; // A-Input
1680 }
1681 return bitpos + channel / 2;
1682 } else {
1683 return -1;
1684 }
1685}
1686
1688 TgcRawData::SlbType slbType) {
1689 int input = -1;
1690 if ((bitpos <= BIT_POS_A_INPUT_ORIGIN) &&
1692 input = 2; // A-Input
1693 } else if ((bitpos <= BIT_POS_B_INPUT_ORIGIN) &&
1695 input = 1; // B-Input
1696 } else if ((bitpos <= BIT_POS_C_INPUT_ORIGIN) &&
1698 input = 0; // C-Input
1699 }
1700 // D-Input is not implemented yet.
1701 else {
1702 return -1; // Invalid bitpos
1703 }
1704 if (input == 0 && slbType != TgcRawData::SLB_TYPE_TRIPLET_WIRE) {
1705 return -1; // Only Wire Triplet has C-input.
1706 }
1707
1708 int channel = 1 - BIT_POS_INPUT_SIZE;
1709 if (slbType == TgcRawData::SLB_TYPE_TRIPLET_WIRE) {
1710 if (input == 2) {
1711 channel += BIT_POS_A_INPUT_ORIGIN; // A-input
1712 } else if (input == 1) {
1713 channel += BIT_POS_B_INPUT_ORIGIN; // B-input
1714 } else {
1715 channel += BIT_POS_C_INPUT_ORIGIN; // C-input
1716 }
1717 channel = 3 * (bitpos - channel) + input;
1718 return channel; // C(0)->B(1)->A(2)->C(3)->B(4)->A(5)-> ...
1719 // ->C(96-3)->B(96-2)->A(96-1)
1720 } else if (slbType == TgcRawData::SLB_TYPE_TRIPLET_STRIP ||
1723 if (input == 2) {
1724 channel += BIT_POS_A_INPUT_ORIGIN; // A-input
1725 } else {
1726 channel += BIT_POS_B_INPUT_ORIGIN; // B-input
1727 }
1728 channel = 2 * (bitpos - channel) + input - 1;
1729 return channel; // B(0)->A(1)->B(2)->A(3)-> ... ->B(64-2)->A(64-1)
1730 } else {
1731 return -1;
1732 }
1733}
1734
1736 const double z, double& r) {
1737 r = exp(-eta); // tan(theta/2)
1738 r = atan(r); // theta/2
1739 r = tan(2. * r); // tan(theta)
1740 r *= std::abs(z); // r=|z|*tan(theta)
1741
1742 return r >= 0.;
1743}
1744
1745bool Muon::TgcRdoToPrepDataToolMT::getEtafromRZ(const double r, const double z,
1746 double& eta) {
1747 double r_tmp = std::abs(r);
1748 double z_tmp = std::abs(z);
1749
1750 if ((r_tmp < std::numeric_limits<double>::epsilon()) &&
1751 (z_tmp < std::numeric_limits<double>::epsilon())) {
1752 return false;
1753 }
1754
1755 eta = std::abs(atan2(r_tmp, z_tmp)); // theta
1756 eta = tan(eta / 2.); // tan(theta/2)
1757 eta = -log(eta); // rapidity=-log(tan(theta/2))
1758 return true;
1759}
1760
1762 const MuonGM::TgcReadoutElement* descriptor,
1763 const Identifier channelId) const {
1764 if (!descriptor || !descriptor->containsId(channelId)) {
1765 ATH_MSG_DEBUG("Illegal OfflineID for TgcReadoutElement"
1766 << m_idHelperSvc->toString(channelId));
1767 return false;
1768 }
1769 return true;
1770}
1771
1773 int& tmp_slbId,
1774 int& tmp_subMatrix,
1775 int& tmp_position) const {
1776 tmp_subMatrix = rd.subMatrix();
1777 if (tmp_subMatrix != 0 && tmp_subMatrix != 1) {
1778 ATH_MSG_DEBUG("getTrackletInfo: subMatrix " << tmp_subMatrix
1779 << " is invalid.");
1780 return false;
1781 }
1782
1783 int tmp_sswId = rd.sswId();
1784 tmp_slbId = rd.slbId();
1785 tmp_position = rd.position();
1786
1787 int tmp_position_delta = tmp_position + rd.delta();
1788 int tmp_slbType = rd.slbType();
1789
1790 if (tmp_position_delta >= BIT_POS_INPUT_SIZE) {
1791 tmp_position = tmp_position_delta - BIT_POS_INPUT_SIZE;
1792 if (tmp_subMatrix == 1) {
1793 if (tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_STRIP) {
1794 tmp_position = BIT_POS_INPUT_SIZE - 1;
1796 "Expected TGC2 Strip position ("
1797 << tmp_position_delta
1798 << ") does not exist and is changed to the edge position "
1799 << tmp_position);
1800 } else if ((tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_WIRE) &&
1801 (tmp_sswId == 7) &&
1802 ((tmp_slbId == 3) || (tmp_slbId == 11))) {
1803 // upper edge SLB of FWD:sbLoc3,11
1804 ATH_MSG_DEBUG("sbLoc " << tmp_slbId + 1
1805 << " doesn't exist for FWD!! (upper "
1806 "edge SLB of FWD:sbLoc3,11)");
1807 return false;
1808 } else if ((tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_WIRE) &&
1809 (tmp_sswId != 7) && (tmp_slbId == 9)) {
1810 // upper edge SLB of EWD:sbLoc9
1811 ATH_MSG_DEBUG("sbLoc " << tmp_slbId + 1
1812 << " doesn't exist for EWD!! (upper "
1813 "edge SLB of EWD:sbLoc9)");
1814 return false;
1815 } else {
1816 // Valid sbLoc,delta,blockpos
1817 tmp_subMatrix = 0;
1818 tmp_slbId++;
1819 }
1820 } else {
1821 tmp_subMatrix = 1;
1822 }
1823 } else if (tmp_position_delta < 0) {
1824 tmp_position = tmp_position_delta + BIT_POS_INPUT_SIZE;
1825 if (tmp_subMatrix == 0) {
1826 if (tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_STRIP) {
1827 tmp_position = 0;
1829 "Expected TGC2 Strip position ("
1830 << tmp_position_delta
1831 << ") does not exist and is changed to the edge position "
1832 << tmp_position);
1833 } else if ((tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_WIRE) &&
1834 (tmp_sswId == 7) &&
1835 ((tmp_slbId == 0) || (tmp_slbId == 8))) {
1836 // bottom edge SLB of FWD:sbLoc0,8
1837 if (tmp_position_delta == -1) { // This case is valid.
1838 tmp_position = 0;
1839 } else {
1840 ATH_MSG_DEBUG("sbLoc "
1841 << tmp_slbId - 1
1842 << " doesn't exist for FWD!! (bottom edge "
1843 "SLB of FWD:sbLoc0,8)");
1844 return false;
1845 }
1846 } else if ((tmp_slbType == TgcRawData::SLB_TYPE_DOUBLET_WIRE) &&
1847 (tmp_sswId != 7) && (tmp_slbId == 0)) {
1848 // bottom edge SLB of EWD:sbLoc0
1849 if (tmp_position_delta == -1) { // This case is valid.
1850 tmp_position = 0;
1851 } else {
1852 ATH_MSG_DEBUG("sbLoc "
1853 << tmp_slbId - 1
1854 << " doesn't exist for EWD!! (bottom edge "
1855 "SLB of EWD:sbLoc0)");
1856 return false;
1857 }
1858 } else {
1859 // Valid sbLoc,delta,
1860 tmp_subMatrix = 1;
1861 tmp_slbId--;
1862 }
1863 } else {
1864 tmp_subMatrix = 0;
1865 }
1866 } else {
1867 tmp_position = tmp_position_delta;
1868 }
1869
1870 return true;
1871}
1872
1874 int RoiRow = static_cast<int>(rd.roi() / 4);
1875 return RoiRow;
1876}
1877
1879 const TgcRawData& rd) const {
1880 int RoiRow = getRoiRow(rd);
1881
1882 if (!rd.isForward() &&
1883 (RoiRow == 3 || RoiRow == 4 || // SSC 2 : ROI 12-19
1884 RoiRow == 7 || RoiRow == 8 || // SSC 4 : ROI 28-35
1885 RoiRow == 11 || RoiRow == 12 || // SSC 6 : ROI 44-51
1886 RoiRow == 23 || RoiRow == 24 // SSC12 : ROI 92-99
1887 )) {
1888 return true;
1889 }
1890 return false;
1891}
1892
1894 const TgcRawData& rd, int& slbsubMatrix, std::array<int, 2>& bitpos_o) {
1895 // This method is used by decodeHiPt
1896 if ((rd.hitId() % 2) == 1) { // 1,3,5
1897 slbsubMatrix = 0;
1898 if ((rd.hsub()) == 0) {
1899 bitpos_o[0] = BIT_POS_B_INPUT_LARGE_R_CH15; // 78
1900 bitpos_o[1] = BIT_POS_A_INPUT_LARGE_R_CH08; // 49
1901 } else if ((rd.hsub()) == 1) {
1902 bitpos_o[0] = BIT_POS_B_INPUT_LARGE_R_CH07; // 86
1903 bitpos_o[1] = BIT_POS_A_INPUT_LARGE_R_CH00; // 57
1904 }
1905 } else { // 2,4,6
1906 slbsubMatrix = 1;
1907 if ((rd.hsub()) == 0) {
1908 bitpos_o[0] = BIT_POS_B_INPUT_SMALL_R_CH15; // 94
1909 bitpos_o[1] = BIT_POS_A_INPUT_SMALL_R_CH08; // 65
1910 } else if ((rd.hsub()) == 1) {
1911 bitpos_o[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
1912 bitpos_o[1] = BIT_POS_A_INPUT_SMALL_R_CH00; // 73
1913 }
1914 }
1915
1916 // In case of WIRE, there are no bit assign.(EWD0 EWD4 FWD0
1917 // FWD1)----------------------------- EWD0 sbLoc = 0 bitpos = 102 : does
1918 // not exist and has 6 channels only (the largest R, RoiRow== 0). EWD4
1919 // sbLoc = 9 bitpos = 73 : does not exist and has 4 channels only (the
1920 // smallest R, RoiRow==36). FWD0 sbLoc = 0, 8 bitpos = 78 : does not exist
1921 // and has 5 channels only (the largest R, RoiRow== 0). FWD1 sbLoc = 3, 11
1922 // bitpos = 73 : does not exist and has 5 channels only (the smallest R,
1923 // RoiTow==15). fixed it by following description.
1924 if (!rd.isForward()) { // Endcap
1925 if ((rd.chip() == 0) && (rd.hitId() == 1) && (rd.hsub() == 1)) {
1926 // chip 0 should have these values and means EWD0's position.
1927 slbsubMatrix = 1;
1928 bitpos_o[0] = BIT_POS_B_INPUT_SMALL_R_CH05; // 104
1929 bitpos_o[1] = BIT_POS_A_INPUT_SMALL_R_CH00; // 73
1930 } else if ((rd.chip() == 3) && (rd.hitId() == 6) &&
1931 (rd.hsub() == 1)) { // EWD4's position
1932 bitpos_o[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
1933 bitpos_o[1] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
1934 }
1935 } else { // Forward
1936 if ((rd.chip() == 0) && (rd.hitId() == 1) &&
1937 (rd.hsub() == 0)) { // FWD0
1938 bitpos_o[0] = BIT_POS_B_INPUT_LARGE_R_CH12; // 81
1939 bitpos_o[1] = BIT_POS_A_INPUT_LARGE_R_CH08; // 49
1940 } else if ((rd.chip() == 1) && (rd.hitId() == 2) &&
1941 (rd.hsub() == 1)) { // FWD1
1942 bitpos_o[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
1943 bitpos_o[1] = BIT_POS_A_INPUT_SMALL_R_CH03; // 70
1944 }
1945 } // end of Forward
1946 // end of fixed------------------------------------------------
1947}
1948
1950 const TgcRawData& rd, const int deltaBeforeConvert,
1951 std::array<int, 4>& bitpos_i, std::array<int, 4>& slbchannel_i,
1952 std::array<int, 4>& slbId_in, std::array<int, 4>& sbLoc_in, int& sswId_i,
1953 const std::array<int, 2>& bitpos_o, std::array<int, 2>& slbchannel_o,
1954 const int slbId_o) const {
1955 // This method is used by decodeHiPt
1956 const int NUM_SLBID_SBLOC_OFFSET_WT =
1957 8; // (see
1958 // https://twiki.cern.ch/twiki/pub/Main/TgcDocument/sbloc-070701.xls)
1959
1960 /*** get bitpos for TGC1 Station ***/
1961
1962 int rdochIn_max = 0;
1963 int rdochIn_min = 0;
1964 int offset_dt = 0;
1965 if (!rd.isForward()) { // EWT
1966 rdochIn_max = 665;
1967 rdochIn_min = 78;
1968 offset_dt = 32;
1969 } else { // FWT
1970 rdochIn_max = 312;
1971 rdochIn_min = 0;
1972 offset_dt = 0;
1973 }
1974
1975 int tmp_rdochannel_i = 0;
1976 int tmp_rdochannel_i2 = 0;
1977 for (int i = 0; i < 2; i++) {
1978 slbchannel_o[i] =
1980 tmp_rdochannel_i = WD_MAP_SIZE * slbId_o + slbchannel_o[i] +
1981 deltaBeforeConvert + offset_dt;
1982 if (tmp_rdochannel_i > rdochIn_max) {
1983 tmp_rdochannel_i = rdochIn_max;
1984 } else if (tmp_rdochannel_i < rdochIn_min) {
1985 tmp_rdochannel_i = rdochIn_min;
1986 }
1987
1988 // Large R <-----------------> Small R
1989 // tmp_rdochannel_i : 0 1 2 3 4 5 6 7 8 9 10 ...
1990 //-------------------------------------------------------------------
1991 // tmp_rdochannel_i/3 : 0 0 0 1 1 1 2 2 2 3 3 ...
1992 // (tmp_rdochannel_i/3)*3 : 0 0 0 3 3 3 6 6 6 9 9 ...
1993 // tmp_rdochannel_i2 (i==0) : 2 2 2 5 5 5 8 8 8 11 11 ...
1994 //-------------------------------------------------------------------
1995 // tmp_rdochannel_i+1 : 1 2 3 4 5 6 7 8 9 10 11 ...
1996 // (tmp_rdochannel_i+1)/3 : 0 0 1 1 1 2 2 2 3 3 3 ...
1997 // ((tmp_rdochannel_i+1)/3)*3 : 0 0 3 3 3 6 6 6 9 9 9 ...
1998 // tmp_rdochannel_i2 (i==1) : -1 -1 2 2 2 5 5 5 8 8 8 ...
1999
2000 if (i == 0) { // get the lower R channel on L3 nearest from bitpos_o[0]
2001 tmp_rdochannel_i2 = (tmp_rdochannel_i / 3) * 3 + 2;
2002 } else { // get the higher R channel on L3 nearest from bitpos_o[1]
2003 tmp_rdochannel_i2 = ((tmp_rdochannel_i + 1) / 3) * 3 - 1;
2004 }
2005
2006 if (tmp_rdochannel_i2 > rdochIn_max) {
2007 tmp_rdochannel_i2 = rdochIn_max;
2008 } else if (tmp_rdochannel_i2 < rdochIn_min) {
2009 tmp_rdochannel_i2 = rdochIn_min + 2; // 2 is added for L3
2010 }
2011
2012 slbId_in[i] = tmp_rdochannel_i / WT_MAP_SIZE;
2013 slbId_in[i + 2] = tmp_rdochannel_i2 / WT_MAP_SIZE;
2014
2015 sbLoc_in[i] = slbId_in[i];
2016 sbLoc_in[i + 2] = slbId_in[i + 2];
2017 if (rd.sector() % 2 == 1) {
2018 // phi1 and phi3 have offset (see
2019 // https://twiki.cern.ch/twiki/pub/Main/TgcDocument/sbloc-070701.xls)
2020 // Endcap sector=1, 3 are phi1 and phi3, and Forward sector=1 is
2021 // phi2.
2022 sbLoc_in[i] += NUM_SLBID_SBLOC_OFFSET_WT;
2023 sbLoc_in[i + 2] += NUM_SLBID_SBLOC_OFFSET_WT;
2024 }
2025
2026 slbchannel_i[i] = tmp_rdochannel_i % WT_MAP_SIZE;
2027 slbchannel_i[i + 2] = tmp_rdochannel_i2 % WT_MAP_SIZE;
2028
2029 bitpos_i[i] =
2031 bitpos_i[i + 2] =
2032 getbitpos(slbchannel_i[i + 2], TgcRawData::SLB_TYPE_TRIPLET_WIRE);
2033 }
2034
2035 if (!rd.isForward()) { // EWT
2036 sswId_i = static_cast<int>(rd.sector() / 2);
2037 } else { // FWT
2038 sswId_i = 2;
2039 }
2040}
2041
2043 const TgcRawData& rd, int& slbsubMatrix, std::array<int, 2>& bitpos_o) {
2044 // This method is used by decodeHiPt
2045 if ((rd.hitId() % 2) == 1) { // 1,3,5::hitId:1-6 for EC, 2-3 for Fw
2046 slbsubMatrix = 0;
2047 if ((rd.hsub()) == 0) {
2048 bitpos_o[0] =
2050 bitpos_o[1] =
2052 } else if ((rd.hsub()) == 1) {
2053 bitpos_o[0] =
2055 bitpos_o[1] =
2057 }
2058 } else { // 2,4,6
2059 slbsubMatrix = 1;
2060 if ((rd.hsub()) == 0) {
2061 bitpos_o[0] =
2063 bitpos_o[1] =
2065 } else if ((rd.hsub()) == 1) {
2066 bitpos_o[0] =
2068 bitpos_o[1] =
2070 }
2071 }
2072}
2073
2075 const TgcRawData& rd, const int deltaBeforeConvert,
2076 std::array<int, 4>& bitpos_i, std::array<int, 4>& slbchannel_i,
2077 int& sbLoc_i, int& sswId_i, const std::array<int, 2>& bitpos_o,
2078 std::array<int, 2>& slbchannel_o) const {
2079 // This method is used by decodeHiPt
2080 //*** get bitpos for TGC1 Station ***//
2081 // ST
2082 int rdochIn_max = ST_MAP_SIZE - 1;
2083 int rdochIn_min = 0;
2084
2085 if ((rd.sector() % 2) == 0) {
2086 if (rd.chip() == 0) {
2087 sbLoc_i = 16; // EST0 (phi0 and phi2) or FST0 (phi0)
2088 } else if (rd.chip() == 1) {
2089 sbLoc_i = 17; // EST1 (phi0 and phi2)
2090 }
2091 } else {
2092 if (rd.chip() == 0) {
2093 sbLoc_i = 24; // EST0 (phi1 and phi3) or FST0 (phi2)
2094 } else if (rd.chip() == 1) {
2095 sbLoc_i = 25; // EST1 (phi1 and phi3)
2096 }
2097 }
2098
2099 for (int i = 0; i < 2; i++) {
2100 slbchannel_o[i] =
2102 slbchannel_i[i] = slbchannel_o[i] + deltaBeforeConvert;
2103 if (slbchannel_i[i] > rdochIn_max) {
2104 slbchannel_i[i] = rdochIn_max;
2105 } else if (slbchannel_i[i] < rdochIn_min) {
2106 slbchannel_i[i] = rdochIn_min;
2107 }
2108
2109 if (i == 0) {
2110 slbchannel_i[i + 2] = slbchannel_i[i] + 1;
2111 } else {
2112 slbchannel_i[i + 2] = slbchannel_i[i] - 1;
2113 }
2114
2115 if (slbchannel_i[i + 2] > rdochIn_max) {
2116 slbchannel_i[i + 2] = rdochIn_max;
2117 } else if (slbchannel_i[i + 2] < rdochIn_min) {
2118 slbchannel_i[i + 2] = rdochIn_min;
2119 }
2120
2121 bitpos_i[i] =
2123 bitpos_i[i + 2] =
2124 getbitpos(slbchannel_i[i + 2], TgcRawData::SLB_TYPE_TRIPLET_STRIP);
2125 }
2126
2127 if (!rd.isForward()) { // EST
2128 sswId_i = static_cast<int>(rd.sector() / 2);
2129 } else { // FST
2130 sswId_i = 2;
2131 }
2132}
2133
2135 const TgcRawData& rd, const int hitId_w, const int sub_w, int& subMatrix_w,
2136 std::array<int, 3>& bitpos_w) const {
2137 // This method is used by getSLIds
2138 // This method assumes sub_w is 0 or 1.
2139 // Protection for other possibility is needed.
2140
2141 // 0 : Index for the largest R channel
2142 // 1 : Index for the smallest R channel
2143 // 2 : Index for the "center" channel
2144
2145 int RoiRow = getRoiRow(rd);
2146 bool isForward = rd.isForward();
2147
2148 if (RoiRow == 0 && !isForward) { // EWD0,SLB0 exception (It has 6 channels
2149 // only, the largest R)
2150 subMatrix_w = 1;
2151 bitpos_w[0] = BIT_POS_B_INPUT_SMALL_R_CH05; // 104
2152 bitpos_w[1] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
2153 bitpos_w[2] = BIT_POS_A_INPUT_SMALL_R_CH00; // 73
2154 } else if (RoiRow == 36 && !isForward) { // EWD4,SLB1 exception (It has 4
2155 // channels only, the smallest R)
2156 subMatrix_w = 1;
2157 bitpos_w[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
2158 bitpos_w[1] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
2159 bitpos_w[2] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
2160 } else if (RoiRow == 0 && isForward) { // FWD0,SLB0 exception (It has 5
2161 // channels only, the largest R)
2162 subMatrix_w = 0;
2163 bitpos_w[0] = BIT_POS_B_INPUT_LARGE_R_CH12; // 81
2164 bitpos_w[1] = BIT_POS_A_INPUT_LARGE_R_CH12; // 45
2165 bitpos_w[2] = BIT_POS_A_INPUT_LARGE_R_CH08; // 49
2166 } else if (RoiRow == 15 && isForward) { // FWD1,SLB1 exception (It has 5
2167 // channels only, the smallest R)
2168 subMatrix_w = 1;
2169 bitpos_w[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
2170 bitpos_w[1] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
2171 bitpos_w[2] = BIT_POS_A_INPUT_SMALL_R_CH03; // 70
2172 } else {
2173 if ((hitId_w % 2) == 0) { // 0, 2, 4
2174 subMatrix_w = 0;
2175 if (sub_w == 0) {
2176 bitpos_w[0] = BIT_POS_B_INPUT_LARGE_R_CH15; // 78
2177 bitpos_w[1] = BIT_POS_A_INPUT_LARGE_R_CH12; // 45
2178 bitpos_w[2] = BIT_POS_A_INPUT_LARGE_R_CH08; // 49
2179 } else if (sub_w == 1) {
2180 bitpos_w[0] = BIT_POS_B_INPUT_LARGE_R_CH07; // 86
2181 bitpos_w[1] = BIT_POS_A_INPUT_LARGE_R_CH04; // 53
2182 bitpos_w[2] = BIT_POS_A_INPUT_LARGE_R_CH00; // 57
2183 }
2184 } else { // 1, 3, 5
2185 subMatrix_w = 1;
2186 if (sub_w == 0) {
2187 bitpos_w[0] = BIT_POS_B_INPUT_SMALL_R_CH15; // 94
2188 bitpos_w[1] = BIT_POS_A_INPUT_SMALL_R_CH12; // 61
2189 bitpos_w[2] = BIT_POS_A_INPUT_SMALL_R_CH08; // 65
2190 } else if (sub_w == 1) {
2191 bitpos_w[0] = BIT_POS_B_INPUT_SMALL_R_CH07; // 102
2192 bitpos_w[1] = BIT_POS_A_INPUT_SMALL_R_CH04; // 69
2193 bitpos_w[2] = BIT_POS_A_INPUT_SMALL_R_CH00; // 73
2194 }
2195 }
2196 }
2197}
2198
2200 const int hitId_s, const int sub_s, int& subMatrix_s,
2201 std::array<int, 3>& bitpos_s) {
2202 // This method is used by getSLIds
2203 // 0 : Index for the largest phi (for A-side forward and C-side backward)
2204 // channel 1 : Index for the smallest phi (for A-side forward and C-side
2205 // backward) channel 2 : Index for the "center" channel
2206
2207 if ((hitId_s % 2) == 0) { // 0, 2, 4
2208 subMatrix_s = 0;
2209 if (sub_s == 0) {
2210 bitpos_s[0] =
2212 bitpos_s[1] =
2214 bitpos_s[2] =
2216 } else if (sub_s == 1) {
2217 bitpos_s[0] =
2219 bitpos_s[1] =
2221 bitpos_s[2] =
2223 }
2224 } else if ((hitId_s % 2) == 1) { // 1, 3, 5
2225 subMatrix_s = 1;
2226 if (sub_s == 0) {
2227 bitpos_s[0] =
2229 bitpos_s[1] =
2231 bitpos_s[2] =
2233 } else if (sub_s == 1) {
2234 bitpos_s[0] =
2236 bitpos_s[1] =
2238 bitpos_s[2] =
2240 }
2241 }
2242}
2243
2245 int deltaBeforeConvert = 0;
2246
2247 if (rd.isStrip()) { // strip
2248 switch (rd.delta()) {
2249 case 5:
2250 deltaBeforeConvert = 6;
2251 break;
2252 case 6:
2253 deltaBeforeConvert = 8;
2254 break;
2255 case 7:
2256 deltaBeforeConvert = 10;
2257 break;
2258 case -4:
2259 deltaBeforeConvert = -5;
2260 break;
2261 case -5:
2262 deltaBeforeConvert = -7;
2263 break;
2264 case -6:
2265 deltaBeforeConvert = -9;
2266 break;
2267 case -7:
2268 deltaBeforeConvert = -12;
2269 break;
2270 default:
2271 deltaBeforeConvert = rd.delta();
2272 break;
2273 }
2274 } else { // wire
2275 switch (rd.delta()) {
2276 case 11:
2277 deltaBeforeConvert = 12;
2278 break;
2279 case 12:
2280 deltaBeforeConvert = 14;
2281 break;
2282 case 13:
2283 deltaBeforeConvert = 16;
2284 break;
2285 case 14:
2286 deltaBeforeConvert = 18;
2287 break;
2288 case 15:
2289 deltaBeforeConvert = 20;
2290 break;
2291 case -12:
2292 deltaBeforeConvert = -13;
2293 break;
2294 case -13:
2295 deltaBeforeConvert = -15;
2296 break;
2297 case -14:
2298 deltaBeforeConvert = -17;
2299 break;
2300 case -15:
2301 deltaBeforeConvert = -19;
2302 break;
2303 default:
2304 deltaBeforeConvert = rd.delta();
2305 break;
2306 }
2307 }
2308
2309 return deltaBeforeConvert;
2310}
2311
2313 bool isBackward = false;
2314
2315 if (!rd.isForward()) { // Endcap
2316 if (((rd.subDetectorId() == ASIDE) && (rd.sector() % 2 == 1)) ||
2317 ((rd.subDetectorId() == CSIDE) && (rd.sector() % 2 == 0))) {
2318 // Aside,phi_odd::Backward
2319 // Cside,phi_even::Backward
2320 isBackward = true;
2321 } else {
2322 // Aside,phi_even::Forward
2323 // Cside,phi_odd::Forward
2324 isBackward = false;
2325 }
2326 } else { // Forward
2327 // Aide::Backward
2328 // Cside::Forward
2329 isBackward = (rd.subDetectorId() == ASIDE);
2330 }
2331
2332 return isBackward;
2333}
2334
2336 const std::array<Identifier, 3>& channelId_wire, double& width_wire,
2337 double& r_wire, double& z_wire) const {
2340 const MuonGM::MuonDetectorManager* muDetMgr = muDetMgrHandle.cptr();
2341 std::array<const MuonGM::TgcReadoutElement*, 3> descriptor_w{
2342 muDetMgr->getTgcReadoutElement(channelId_wire[0]),
2343 muDetMgr->getTgcReadoutElement(channelId_wire[1]),
2344 muDetMgr->getTgcReadoutElement(channelId_wire[2])};
2345 for (int i = 0; i < 3; i++) {
2346 if (!isOfflineIdOKForTgcReadoutElement(descriptor_w[i],
2347 channelId_wire[i])) {
2348 return false;
2349 }
2350 }
2351
2352 Amg::Vector3D position_w = descriptor_w[2]->channelPos(channelId_wire[2]);
2353 Amg::Vector2D loc_hitPos_w{Amg::Vector2D::Zero()};
2354 bool onSurface_w = descriptor_w[2]
2355 ->surface(channelId_wire[2])
2356 .globalToLocal(position_w, position_w, loc_hitPos_w);
2357 if (!onSurface_w) {
2359 "Muon::TgcRdoToPrepDataToolMT::getSLWireGeometry Amg::Vector2D* "
2360 "loc_hitPos_w is null.");
2361 return false;
2362 }
2363 Amg::Vector2D tmp_hitPos_w{Amg::Vector2D::Zero()};
2364
2365 std::array<int, 3> gasGap_w{}, channel_w{};
2366 for (int i = 0; i < 3; i++) {
2367 gasGap_w[i] = m_idHelperSvc->tgcIdHelper().gasGap(channelId_wire[i]);
2368 channel_w[i] = m_idHelperSvc->tgcIdHelper().channel(channelId_wire[i]);
2369 }
2370
2371 std::array<double, 3> tmp_r_w{}, tmp_phi_w{}, tmp_eta_w{};
2372
2373 std::array<Amg::Vector3D, 3> tmp_position_w{
2374 make_array<Amg::Vector3D, 3>(Amg::Vector3D::Zero())};
2375 for (int i = 0; i < 3; i += 2) { // i=0 and 2
2376 tmp_position_w[i] = descriptor_w[i]->channelPos(channelId_wire[i]);
2377 tmp_r_w[i] = tmp_position_w[i].perp();
2378 tmp_phi_w[i] = tmp_position_w[i].phi();
2379 tmp_eta_w[i] = tmp_position_w[i].eta();
2380
2381 double half_width =
2382 descriptor_w[i]->gangRadialLength(gasGap_w[i], channel_w[i]) / 2.;
2383 if (half_width < s_cutDropPrdsWithZeroWidth / 2. &&
2384 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero
2385 // are dropped.
2386 return false;
2387 }
2388 // add half widths of edge channels
2389 if (i == 0) {
2390 tmp_r_w[0] += half_width;
2391 } else if (i == 2) {
2392 tmp_r_w[2] -= half_width;
2393 }
2394 }
2395
2396 bool flag_geteta_w =
2397 getEtafromRZ(tmp_r_w[0], tmp_position_w[0].z(), tmp_eta_w[0]);
2398 bool flag_getr_w =
2399 getRfromEtaZ(tmp_eta_w[0], tmp_position_w[2].z(), tmp_r_w[0]);
2400 if (!flag_geteta_w || !flag_getr_w) {
2402 "TgcRdoToPrepDataToolMT::getSLWireGeometry::failed to getR on "
2403 "L7!!");
2404 return false;
2405 }
2406 width_wire = tmp_r_w[0] - tmp_r_w[2];
2407 double gang = descriptor_w[2]->gangShortWidth(gasGap_w[2], channel_w[2]) +
2408 width_wire / 2.;
2409 tmp_hitPos_w[Trk::locX] = gang;
2410 tmp_hitPos_w[Trk::locY] = ((loc_hitPos_w)[Trk::loc2]);
2411
2412 Amg::Vector3D tmp_wire_gp;
2413 descriptor_w[2]
2414 ->surface(channelId_wire[2])
2415 .localToGlobal(tmp_hitPos_w, tmp_wire_gp, tmp_wire_gp);
2416 z_wire = tmp_wire_gp.z();
2417 r_wire = tmp_r_w[2] + width_wire / 2.;
2418
2419 return true;
2420}
2421
2423 const std::array<Identifier, 3>& channelId_strip, const bool isBackward,
2424 const bool isAside, double& width_strip, double& theta_strip) const {
2427 const MuonGM::MuonDetectorManager* muDetMgr = muDetMgrHandle.cptr();
2428 std::array<const MuonGM::TgcReadoutElement*, 3> descriptor_s{
2429 muDetMgr->getTgcReadoutElement(channelId_strip[0]),
2430 muDetMgr->getTgcReadoutElement(channelId_strip[1]),
2431 muDetMgr->getTgcReadoutElement(channelId_strip[2])};
2432 for (int i = 0; i < 3; i++) {
2433 if (!isOfflineIdOKForTgcReadoutElement(descriptor_s[i],
2434 channelId_strip[i])) {
2435 return false;
2436 }
2437 }
2438
2439 Amg::Vector3D position_s =
2440 Amg::Vector3D(descriptor_s[1]->channelPos(channelId_strip[1]));
2441 Amg::Vector2D loc_hitPos_s;
2442 bool onSurface_s = descriptor_s[1]
2443 ->surface(channelId_strip[1])
2444 .globalToLocal(position_s, position_s, loc_hitPos_s);
2445 if (!onSurface_s) {
2447 "Muon::TgcRdoToPrepDataToolMT::getSLStripGeometry Amg::Vector2D* "
2448 "loc_hitPos_s is null.");
2449 return false;
2450 }
2451 Amg::Vector2D tmp_hitPos_s{Amg::Vector2D::Zero()};
2452
2453 std::array<int, 3> gasGap_s, channel_s{};
2454 for (int i = 0; i < 3; i++) {
2455 gasGap_s[i] = m_idHelperSvc->tgcIdHelper().gasGap(channelId_strip[i]);
2456 channel_s[i] = m_idHelperSvc->tgcIdHelper().channel(channelId_strip[i]);
2457 }
2458
2459 std::array<Amg::Vector3D, 3> localPos{Amg::Vector3D::Zero()};
2460 for (int i = 0; i < 3; i += 2) { // i=0 and 2
2461 localPos[i] = descriptor_s[i]->transform(channelId_strip[i]).inverse() *
2462 descriptor_s[i]->channelPos(channelId_strip[i]);
2463 }
2464
2465 bool flag_reverse = false;
2466 std::array<int, 2> index_strip{};
2467
2468 if (!isBackward) { // Forward chamber
2469 if (isAside) { // Aside/Forward Chamber
2470 index_strip[0] = 2;
2471 index_strip[1] = 0;
2472 flag_reverse = true;
2473 } else { // Cside/Forward Chamber
2474 index_strip[0] = 0;
2475 index_strip[1] = 2;
2476 flag_reverse = false;
2477 }
2478 } else { // Backward chamber
2479 if (isAside) { // Aside/Backward Chamber
2480 index_strip[0] = 0;
2481 index_strip[1] = 2;
2482 flag_reverse = true;
2483 } else { // Cside/Backward Chamber
2484 index_strip[0] = 2;
2485 index_strip[1] = 0;
2486 flag_reverse = false;
2487 }
2488 }
2489
2490 double stripMaxX = descriptor_s[index_strip[0]]->stripHighEdgeLocX(
2491 gasGap_s[index_strip[0]], channel_s[index_strip[0]],
2492 localPos[index_strip[0]].z());
2493 double stripMinX = descriptor_s[index_strip[1]]->stripLowEdgeLocX(
2494 gasGap_s[index_strip[1]], channel_s[index_strip[1]],
2495 localPos[index_strip[1]].z());
2496 width_strip = stripMaxX - stripMinX;
2497 double strip = stripMinX + width_strip / 2.;
2498 if (flag_reverse) {
2499 strip *= -1.;
2500 }
2501
2502 tmp_hitPos_s[Trk::locX] = strip;
2503 tmp_hitPos_s[Trk::locY] = loc_hitPos_s[Trk::loc2];
2504
2505 int index_strip_gp = 0;
2506 if (!isBackward) {
2507 index_strip_gp = 0;
2508 } else {
2509 index_strip_gp = 2;
2510 }
2511 Amg::Vector3D tmp_strip_gp;
2512 descriptor_s[index_strip_gp]
2513 ->surface(channelId_strip[index_strip_gp])
2514 .localToGlobal(tmp_hitPos_s, tmp_strip_gp, tmp_strip_gp);
2515 theta_strip = atan2(tmp_strip_gp.y(), tmp_strip_gp.x());
2516
2517 return true;
2518}
2519
2521 const std::array<const MuonGM::TgcReadoutElement*, 2>& descriptor_o,
2522 const std::array<Identifier, 2>& channelIdOut,
2523 const std::array<int, 2>& gasGap_o, const std::array<int, 2>& channel_o,
2524 double& width_o, double& hit_position_o, Amg::Vector2D& tmp_hitPos_o,
2525 Identifier& channelIdOut_tmp) const {
2526 // This method is used by decodeHiPt
2527 std::array<Amg::Vector3D, 2> position_o{
2528 make_array<Amg::Vector3D, 2>(Amg::Vector3D::Zero())};
2529 std::array<double, 2> tmp_phi_o{}, tmp_eta_o{}, tmp_r_o{};
2530
2531 for (int i = 0; i < 2; i++) {
2532 position_o[i] = descriptor_o[i]->channelPos(channelIdOut[i]);
2533 tmp_r_o[i] = position_o[i].perp();
2534 tmp_phi_o[i] = position_o[i].phi();
2535 tmp_eta_o[i] = position_o[i].phi();
2536 // add half widths of edge channels
2537 double half_width =
2538 descriptor_o[i]->gangRadialLength(gasGap_o[i], channel_o[i]) / 2.;
2539 if (half_width < s_cutDropPrdsWithZeroWidth / 2. &&
2540 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero
2541 // are dropped.
2542 return false;
2543 }
2544 if (i == 0) {
2545 tmp_r_o[0] += half_width;
2546 } else {
2547 tmp_r_o[1] -= half_width;
2548 }
2549 }
2550
2551 bool flag_geteta_o =
2552 getEtafromRZ(tmp_r_o[0], position_o[0].z(), tmp_eta_o[0]);
2553 bool flag_getr_o =
2554 getRfromEtaZ(tmp_eta_o[0], position_o[1].z(), tmp_r_o[0]);
2555 if (!flag_geteta_o || !flag_getr_o) {
2557 "TgcRdoToPrepDataToolMT::getPosAndIdWireOut::failed to getR on "
2558 "L7!!");
2559 return false;
2560 }
2561
2562 width_o = tmp_r_o[0] - tmp_r_o[1];
2563 // X-coordinate
2564 hit_position_o =
2565 descriptor_o[1]->gangShortWidth(gasGap_o[1], channel_o[1]) +
2566 width_o / 2;
2567 tmp_hitPos_o[Trk::locX] = (hit_position_o);
2568 // Y-coordinate
2569 Amg::Vector3D position_out =
2570 Amg::Vector3D(descriptor_o[1]->channelPos(channelIdOut[1]));
2571 // dummy global pos
2572 Amg::Vector2D loc_hitPos_o;
2573 bool onSurface_o =
2574 descriptor_o[1]
2575 ->surface(channelIdOut[1])
2576 .globalToLocal(position_out, position_out, loc_hitPos_o);
2577 if (!onSurface_o) {
2579 "Muon::TgcRdoToPrepDataToolMT::getPosAndIdWireOut Amg::Vector2D* "
2580 "loc_hitPos_o is null.");
2581 return false;
2582 }
2583 tmp_hitPos_o[Trk::locY] = loc_hitPos_o[Trk::loc2];
2584
2585 channelIdOut_tmp = channelIdOut[1];
2586
2587 return true;
2588}
2589
2591 const std::array<const MuonGM::TgcReadoutElement*, 2>& descriptor_o,
2592 const std::array<Identifier, 2>& channelIdOut,
2593 const std::array<int, 2>& gasGap_o, const std::array<int, 2>& channel_o,
2594 double& width_o, double& hit_position_o, Amg::Vector2D& tmp_hitPos_o,
2595 Identifier& channelIdOut_tmp, const bool isBackward,
2596 const bool isAside) const {
2597 // This method is used by decodeHiPt
2598 // Currently, this method always returns true.
2599 std::array<Amg::Vector3D, 2> localpos_o{
2600 make_array<Amg::Vector3D, 2>(Amg::Vector3D::Zero())};
2601 for (int i = 0; i < 2; i++) {
2602 localpos_o[i] = descriptor_o[i]->transform(channelIdOut[i]).inverse() *
2603 descriptor_o[i]->channelPos(channelIdOut[i]);
2604 }
2605
2606 std::array<int, 3> index{};
2607 bool flag_reverse = false;
2608 if (!isBackward) { // Forward chamber
2609 index[2] = 0;
2610 if (isAside) { // Aside/Forward Chamber
2611 index[0] = 1;
2612 index[1] = 0;
2613 flag_reverse = true;
2614 } else { // Cside/Forward Chamber
2615 index[0] = 0;
2616 index[1] = 1;
2617 flag_reverse = false;
2618 }
2619 } else { // Backward chamber
2620 index[2] = 1;
2621 if (isAside) { // Aside/Backward Chamber
2622 index[0] = 0;
2623 index[1] = 1;
2624 flag_reverse = true;
2625 } else { // Cside/Backward Chamber
2626 index[0] = 1;
2627 index[1] = 0;
2628 flag_reverse = false;
2629 }
2630 }
2631
2632 double stripMax = descriptor_o[index[0]]->stripHighEdgeLocX(
2633 gasGap_o[index[0]], channel_o[index[0]], localpos_o[index[0]].z());
2634 double stripMin = descriptor_o[index[1]]->stripLowEdgeLocX(
2635 gasGap_o[index[1]], channel_o[index[1]], localpos_o[index[1]].z());
2636 width_o = stripMax - stripMin;
2637 // X-coordinate
2638 hit_position_o = stripMin + width_o / 2.;
2639 if (flag_reverse) {
2640 hit_position_o *= -1.;
2641 }
2642 tmp_hitPos_o[Trk::locX] = hit_position_o;
2643 // Y-coordinate
2644 Amg::Vector3D position_out =
2645 Amg::Vector3D(descriptor_o[1]->channelPos(channelIdOut[1]));
2646 // dummy global pos
2647 Amg::Vector2D loc_hitPos_o{Amg::Vector2D::Zero()};
2648 bool onSurface_o =
2649 descriptor_o[1]
2650 ->surface(channelIdOut[1])
2651 .globalToLocal(position_out, position_out, loc_hitPos_o);
2652 if (!onSurface_o) {
2654 "Muon::TgcRdoToPrepDataToolMT::getPosAndIdStripOut Amg::Vector2D* "
2655 "loc_hitPos_o is null.");
2656 return false;
2657 }
2658 tmp_hitPos_o[Trk::locY] = loc_hitPos_o[Trk::loc2];
2659
2660 channelIdOut_tmp = channelIdOut[index[2]];
2661
2662 return true;
2663}
2664
2666 const std::array<const MuonGM::TgcReadoutElement*, 4>& descriptor_i,
2667 const std::array<Identifier, 4>& channelIdIn,
2668 const std::array<int, 4>& gasGap_i, const std::array<int, 4>& channel_i,
2669 double& width_i, double& hit_position_i, Amg::Vector2D& tmp_hitPos_i,
2670 Identifier& channelIdIn_tmp) const {
2671 // This method is used by decodeHiPt
2672 int flag_boundary_i = 0;
2673 if (descriptor_i[1]->chamberType() == descriptor_i[3]->chamberType()) {
2674 // in case lower edge is not chamber boundary
2675 if (gasGap_i[1] ==
2676 gasGap_i[3]) { // in case that edge channel is on L3; use [1]
2677 flag_boundary_i = 1;
2678 } else { // in case that edge channel is not on L3; use [3]
2679 flag_boundary_i = 3;
2680 }
2681 } else if (descriptor_i[0]->chamberType() ==
2682 descriptor_i[2]->chamberType()) {
2683 // in case higher edge is not chamber boundary
2684 if (gasGap_i[0] ==
2685 gasGap_i[2]) { // in case that edge channel is on L3; use [0]
2686 flag_boundary_i = 0;
2687 } else { // in case that edge channel is not on L3; use [2]
2688 flag_boundary_i = 2;
2689 }
2690 } else {
2692 "TgcRdoToPrepDataToolMT::getPosAndIdWireIn::ROI has 3 readout "
2693 "elements!!");
2694 return false;
2695 }
2696
2697 channelIdIn_tmp = channelIdIn[flag_boundary_i];
2700 const MuonGM::MuonDetectorManager* muDetMgr = muDetMgrHandle.cptr();
2701 const MuonGM::TgcReadoutElement* descriptor_iw =
2702 muDetMgr->getTgcReadoutElement(channelIdIn_tmp);
2703 if (!isOfflineIdOKForTgcReadoutElement(descriptor_iw, channelIdIn_tmp)) {
2704 return false;
2705 }
2706
2707 std::array<double, 3> tmp_r_i{}, tmp_phi_i{}, tmp_eta_i{};
2708
2709 std::array<Amg::Vector3D, 3> position_i{
2710 descriptor_i[0]->channelPos(channelIdIn[0]),
2711 descriptor_i[1]->channelPos(channelIdIn[1]),
2712 descriptor_iw->channelPos(channelIdIn_tmp)};
2713
2714 for (int i = 0; i < 3; i++) {
2715 tmp_r_i[i] = position_i[i].perp();
2716 tmp_phi_i[i] = position_i[i].phi();
2717 tmp_eta_i[i] = position_i[i].eta();
2718
2719 if (i < 2) {
2720 // add half widths of edge channels
2721 double half_width =
2722 descriptor_i[i]->gangRadialLength(gasGap_i[i], channel_i[i]) /
2723 2.;
2724 if (half_width < s_cutDropPrdsWithZeroWidth / 2. &&
2725 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are
2726 // zero are dropped.
2727 return false;
2728 }
2729 if (i == 0) {
2730 tmp_r_i[0] += half_width;
2731 } else {
2732 tmp_r_i[1] -= half_width;
2733 }
2734
2735 bool flag_geteta_i =
2736 getEtafromRZ(tmp_r_i[i], position_i[i].z(), tmp_eta_i[i]);
2737 bool flag_getr_i =
2738 getRfromEtaZ(tmp_eta_i[i], position_i[2].z(), tmp_r_i[i]);
2739
2740 if (!flag_geteta_i || !flag_getr_i) {
2742 "TgcRdoToPrepDataToolMT::getPosAndIdWireIn::failed to "
2743 "getRIn"
2744 << i << " on L3!!");
2745 return false;
2746 }
2747 }
2748 }
2749
2750 width_i = tmp_r_i[0] - tmp_r_i[1];
2751 if (width_i < 0.) {
2753 "TgcRdoToPrepDataToolMT::getPosAndIdWireIn::minus value width_i = "
2754 << width_i);
2755 return false;
2756 }
2757
2758 int gasGap_tmp = m_idHelperSvc->tgcIdHelper().gasGap(channelIdIn_tmp);
2759 int channel_tmp = m_idHelperSvc->tgcIdHelper().channel(channelIdIn_tmp);
2760 double half_width =
2761 descriptor_iw->gangRadialLength(gasGap_tmp, channel_tmp) / 2.;
2762 if (half_width < s_cutDropPrdsWithZeroWidth / 2. &&
2763 m_dropPrdsWithZeroWidth) { // Invalid PRD's whose widths are zero are
2764 // dropped.
2765 return false;
2766 }
2767 if ((flag_boundary_i % 2) ==
2768 1) { // in case lower edge is not chamber boundary
2769 tmp_r_i[2] -= half_width;
2770 hit_position_i =
2771 descriptor_iw->gangShortWidth(gasGap_tmp, channel_tmp) -
2772 (tmp_r_i[2] - tmp_r_i[1]) + width_i / 2.;
2773 } else { // in case higher edge is not chamber boundary
2774 tmp_r_i[2] += half_width;
2775 hit_position_i = descriptor_iw->gangLongWidth(gasGap_tmp, channel_tmp) +
2776 (tmp_r_i[0] - tmp_r_i[2]) - width_i / 2.;
2777 }
2778
2779 // X-coordinate
2780 tmp_hitPos_i[Trk::locX] = hit_position_i;
2781 Amg::Vector3D position_in = descriptor_i[1]->channelPos(channelIdIn[1]);
2782 // dummy global pos
2783 Amg::Vector2D loc_hitPos_i{Amg::Vector2D::Zero()};
2784 bool onSurface_i =
2785 descriptor_i[1]
2786 ->surface(channelIdIn[1])
2787 .globalToLocal(position_in, position_in, loc_hitPos_i);
2788 if (!onSurface_i) {
2790 "Muon::TgcRdoToPrepDataToolMT::getPosAndIdWireIn Amg::Vector2D* "
2791 "loc_hitPos_i is null.");
2792 return false;
2793 }
2794 // Y-coordinate
2795 tmp_hitPos_i[Trk::locY] = loc_hitPos_i[Trk::loc2];
2796
2797 return true;
2798}
2799
2801 const std::array<const MuonGM::TgcReadoutElement*, 4>& descriptor_i,
2802 const std::array<Identifier, 4>& channelIdIn,
2803 const std::array<int, 4>& gasGap_i, const std::array<int, 4>& channel_i,
2804 double& width_i, double& hit_position_i, Amg::Vector2D& tmp_hitPos_i,
2805 Identifier& channelIdIn_tmp, const bool isBackward,
2806 const bool isAside) const {
2807 // This method is used by decodeHiPt
2808 int flag_isL3 = -1;
2809 // which bitpos is Layer3?
2810 for (int i = 0; i < 4; i++) {
2811 if (gasGap_i[i] == 3) {
2812 flag_isL3 = i;
2813 break;
2814 }
2815 }
2816 if (flag_isL3 < 0 || flag_isL3 >= 4) {
2817 ATH_MSG_DEBUG("getPosAndIdStripIn: Any bitpos is not at Layer3!");
2818 return false;
2819 }
2820
2821 channelIdIn_tmp = channelIdIn[flag_isL3];
2824 const MuonGM::MuonDetectorManager* muDetMgr = muDetMgrHandle.cptr();
2825 const MuonGM::TgcReadoutElement* descriptor_is =
2826 muDetMgr->getTgcReadoutElement(channelIdIn_tmp);
2827 if (!isOfflineIdOKForTgcReadoutElement(descriptor_is, channelIdIn_tmp)) {
2828 return true;
2829 }
2830
2831 std::array<double, 3> tmp_r_i{}, tmp_phi_i{}, tmp_eta_i{};
2832 std::array<Amg::Vector3D, 3> position_is{
2833 make_array<Amg::Vector3D, 3>(Amg::Vector3D::Zero())};
2834 for (int i = 0; i < 3; i++) {
2835 if (i < 2) {
2836 position_is[i] = descriptor_i[i]->channelPos(channelIdIn[i]);
2837 } else {
2838 position_is[i] = descriptor_is->channelPos(channelIdIn_tmp);
2839 }
2840 tmp_r_i[i] = position_is[i].perp();
2841 tmp_phi_i[i] = position_is[i].phi();
2842 tmp_eta_i[i] = position_is[i].eta();
2843 }
2844
2845 std::array<int, 2> index{};
2846 bool flag_reverse = false;
2847 if (!isBackward) { // Forward chamber
2848 if (isAside) { // Aside/Forward Chamber
2849 index[0] = 1;
2850 index[1] = 0;
2851 flag_reverse = true;
2852 } else { // Cside/Forward Chamber
2853 index[0] = 0;
2854 index[1] = 1;
2855 flag_reverse = false;
2856 }
2857 } else { // Backward chamber
2858 if (isAside) { // Aside/Backward Chamber
2859 index[0] = 0;
2860 index[1] = 1;
2861 flag_reverse = true;
2862 } else { // Cside/Backward Chamber
2863 index[0] = 1;
2864 index[1] = 0;
2865 flag_reverse = false;
2866 }
2867 }
2868
2869 std::array<Amg::Vector3D, 2> localpos_i{
2870 make_array<Amg::Vector3D, 2>(Amg::Vector3D::Zero())};
2871 for (int i = 0; i < 2; i++) {
2872 localpos_i[i] = descriptor_i[i]->transform(channelIdIn[i]).inverse() *
2873 descriptor_i[i]->channelPos(channelIdIn[i]);
2874 }
2875 double stripMaxX = descriptor_i[index[0]]->stripHighEdgeLocX(
2876 gasGap_i[index[0]], channel_i[index[0]], localpos_i[index[0]].z());
2877 double stripMinX = descriptor_i[index[1]]->stripLowEdgeLocX(
2878 gasGap_i[index[1]], channel_i[index[1]], localpos_i[index[1]].z());
2879 width_i = stripMaxX - stripMinX;
2880 // X-coordinate
2881 hit_position_i = stripMinX + width_i / 2.;
2882 if (flag_reverse) {
2883 hit_position_i *= -1.;
2884 }
2885 tmp_hitPos_i[Trk::locX] = hit_position_i;
2886 // Y-coordinate
2887 Amg::Vector3D position_in =
2888 Amg::Vector3D(descriptor_i[1]->channelPos(channelIdIn[1]));
2889 // dummy global pos
2890 Amg::Vector2D loc_hitPos_i;
2891 bool onSurface_i =
2892 descriptor_i[1]
2893 ->surface(channelIdIn[1])
2894 .globalToLocal(position_in, position_in, loc_hitPos_i);
2895 if (!onSurface_i) {
2897 "Muon::TgcRdoToPrepDataToolMT::getPosAndIdStripIn Amg::Vector2D* "
2898 "loc_hitPos_i is null.");
2899 return false;
2900 }
2901 tmp_hitPos_i[Trk::locY] = loc_hitPos_i[Trk::loc2];
2902
2903 return true;
2904}
2905
2906// RDOHighPtID --> (Sim)HighPtID --> OfflineID --> ReadoutID --> getSLBID
2908 int& sswId_o, int& sbLoc_o,
2909 int& slbId_o) const {
2910 int index = static_cast<int>(rd.index());
2911 int chip = static_cast<int>(rd.chip());
2912 int hitId = static_cast<int>(rd.hitId());
2913
2914 // getSimHighPtIDfromRDOHighPtID changes index, chip and hitId.
2915 bool found = state.cabling->getSimHighPtIDfromRDOHighPtID(
2916 rd.isForward(), rd.isStrip(), index, chip, hitId);
2917 if (!found) {
2918 ATH_MSG_DEBUG("Failed to get SimHighPtID from RDOHighPtID for Pivot "
2919 << (rd.isStrip() ? "Strip" : "Wire"));
2920 return false;
2921 }
2922
2923 // conversion for Run3
2924 uint16_t tmprodId, tmpsector;
2925 convertToRun2(rd, tmprodId, tmpsector);
2926
2927 Identifier dummyId;
2928 if (rd.rodId() > 12) { // Run3
2929 found = state.cabling->getOfflineIDfromHighPtID(
2930 dummyId, rd.subDetectorId(), tmprodId, tmpsector, rd.isStrip(),
2931 rd.isForward(), index, chip, hitId, rd.hsub());
2932 } else {
2933 found = state.cabling->getOfflineIDfromHighPtID(
2934 dummyId, rd.subDetectorId(), rd.rodId(), rd.sector(), rd.isStrip(),
2935 rd.isForward(), index, chip, hitId, rd.hsub());
2936 }
2937
2938 if (!found) {
2939 ATH_MSG_DEBUG("Failed to get offlineID from HighPtID for Pivot "
2940 << (rd.isStrip() ? "Strip" : "Wire"));
2941 return false;
2942 }
2943
2944 std::array<int, 3> dummy_i{};
2945 found = state.cabling->getReadoutIDfromOfflineID(
2946 dummyId, dummy_i[0], dummy_i[1], sswId_o, sbLoc_o, dummy_i[2]);
2947 if (!found) {
2948 ATH_MSG_DEBUG("Failed to get ReadoutID from OfflineID for Pivot "
2949 << (rd.isStrip() ? "Strip" : "Wire"));
2950 return false;
2951 }
2952
2953 std::array<int, 2> i_o{};
2954 std::array<bool, 2> b_o{false, false};
2955 if (rd.rodId() > 12) { // Run3
2956 found = state.cabling->getSLBIDfromReadoutID(
2957 i_o[0], b_o[0], b_o[1], i_o[1], slbId_o, rd.subDetectorId(),
2958 tmprodId, sswId_o, sbLoc_o);
2959 } else {
2960 found = state.cabling->getSLBIDfromReadoutID(
2961 i_o[0], b_o[0], b_o[1], i_o[1], slbId_o, rd.subDetectorId(),
2962 rd.rodId(), sswId_o, sbLoc_o);
2963 }
2964 if (!found) {
2965 ATH_MSG_DEBUG("Failed to get SLBID from ReadoutID for Pivot "
2966 << (rd.isStrip() ? "Strip" : "Wire"));
2967 return false;
2968 }
2969
2970 return true;
2971}
2973 const bool isStrip, const TgcRawData& rd,
2974 std::array<Identifier, 3>& channelId, int& index, int& chip, int& hitId,
2975 int& sub, int& sswId, int& sbLoc, int& subMatrix,
2976 std::array<int, 3>& bitpos, const bool isBoundary, const TgcRdo* rdoColl,
2977 const int index_w, const int chip_w, const int hitId_w,
2978 const int sub_w) const
2979
2980{
2981 bool found = state.cabling->getHighPtIDfromROINumber(
2982 rd.roi(), rd.isForward(),
2983 isStrip, // get HitID of HPT Board
2984 index, chip, hitId, sub);
2985 if (!found) {
2986 ATH_MSG_DEBUG("Failed to get HighPtID from ROINumber for "
2987 << (!isStrip ? "Wire" : "Strip"));
2988 return false;
2989 }
2990
2992 rd.isForward(), isStrip, index, chip, hitId);
2993 if (!found) {
2994 ATH_MSG_DEBUG("Failed to get SimHighPtID from RDOHighPtID for "
2995 << (!isStrip ? "Wire" : "Strip"));
2996 return false;
2997 }
2998
2999 Identifier offlineId;
3000 found = state.cabling->getOfflineIDfromHighPtID(
3001 offlineId, rd.subDetectorId(), rd.rodId(), rd.sector(), isStrip,
3002 rd.isForward(), index, chip, hitId, sub);
3003 if (!found) {
3004 ATH_MSG_DEBUG("Failed to get OfflineID from HighPtID for "
3005 << (!isStrip ? "Wire" : "Strip"));
3006 return false;
3007 }
3008
3009 if (!isStrip || !isBoundary) { // Wire or strip whose ROI not including
3010 // chamber boundary
3011 channelId[1] = offlineId;
3012 std::array<int, 3> dummy_i{};
3013 found = state.cabling->getReadoutIDfromOfflineID(
3014 channelId[1], dummy_i[0], dummy_i[1], sswId, sbLoc, dummy_i[2]);
3015 if (!found) {
3016 ATH_MSG_DEBUG("Failed to get ReadoutID from OfflineID for "
3017 << (!isStrip ? "Wire" : "Strip"));
3018 return false;
3019 }
3020 } else { // --> solving the chamber boundary of strip
3021 sswId = rd.sector() + 3; // SSW3: M3-EC phi0, SSW4: M3-EC phi1, SSW5:
3022 // M3-EC phi2, SSW6: M3-EC phi3
3023
3024 // Loop over all HiPt Strip to find an associated one to obtain sbLoc
3025 bool exist_hipt_s = getSbLocOfEndcapStripBoundaryFromHiPt(state,
3026 rd, sbLoc, rdoColl, index_w, chip_w, hitId_w, sub_w);
3027 if (!exist_hipt_s) {
3028 // Loop over all Tracklet Strip to find an associated one to obtain
3029 // sbLoc
3030 bool exist_tracklet_s = getSbLocOfEndcapStripBoundaryFromTracklet(state,
3031 rd, sbLoc, rdoColl, index_w, chip_w, hitId_w, sub_w);
3032 if (!exist_tracklet_s) {
3034 "Failed to find correspond Tracklet_strip for SL!!");
3035 return false;
3036 }
3037 }
3038 }
3039
3040 if (!isStrip) { // wire
3041 getBitPosWire(rd, hitId, sub, subMatrix, bitpos);
3042 } else { // strip
3043 getBitPosStrip(hitId, sub, subMatrix, bitpos);
3044 }
3045
3046 for (int i = 0; i < 3; i++) {
3047 if (i == 1 && (!isStrip || !isBoundary)) {
3048 continue;
3049 }
3050
3051 found = state.cabling->getOfflineIDfromReadoutID(
3052 channelId[i], rd.subDetectorId(), rd.rodId(), sswId, sbLoc,
3053 bitpos[i]);
3054 if (!found) {
3055 ATH_MSG_DEBUG("Failed to get OfflineID from ReadoutID for "
3056 << (!isStrip ? "Wire" : "Strip"));
3057 if (!isStrip || i == 1) {
3058 ATH_MSG_DEBUG("subDetectorId = "
3059 << rd.subDetectorId()
3060 << ", rodId = " << rd.rodId()
3061 << ", sswId = " << sswId << ", slbId = " << sbLoc
3062 << ", bitpos_" << (!isStrip ? "w" : "s") << "["
3063 << i << "] = " << bitpos[i]);
3064 }
3065 return false;
3066 }
3067 }
3068
3069 return true;
3070}
3071
3073 const TgcRawData& rd, int& sbLoc, const TgcRdo* rdoColl, const int index_w,
3074 const int chip_w, const int hitId_w, const int sub_w) const {
3075
3076 bool exist_hipt_s = false;
3077
3078 // Get trackletIds of three candidates
3079 int trackletIdStripFirst{-1}, trackletIdStripSecond{-1},
3080 trackletIdStripThird{-1};
3082 static_cast<int>(rd.roi()), trackletIdStripFirst, trackletIdStripSecond,
3083 trackletIdStripThird);
3084
3085 // Loop over all HiPt Strip to find an associated one
3086 for (const TgcRawData* rdH0 : *rdoColl) {
3087
3088 // conversion for Run3
3089 uint16_t tmprodId, tmpsector;
3090 convertToRun2(rdH0, tmprodId, tmpsector);
3091 const TgcRawData rdH(rdH0->bcTag(), rdH0->subDetectorId(), tmprodId,
3092 rdH0->l1Id(), rdH0->bcId(), rdH0->isStrip(),
3093 rdH0->isForward(), tmpsector, rdH0->chip(),
3094 rdH0->index(), rdH0->isHipt(), rdH0->hitId(),
3095 rdH0->hsub(), rdH0->delta(), rdH0->inner());
3096
3097 if ((rdH.type() == TgcRawData::TYPE_HIPT) && // HiPt
3098 (rdH.isHipt()) && // HiPt flag is required
3099 (rdH.isStrip()) && // Strip
3100 (!rdH.isForward()) && // Endcap
3101 (rdH.bcTag() == rd.bcTag()) && // The same timing
3102 (rdH.subDetectorId() == rd.subDetectorId()) && // The same side
3103 (rdH.rodId() == rd.rodId()) && // The same ROD
3104 (rdH.sector() == rd.sector()) // The same sector (1/48 phi)
3105 ) {
3106
3107 // Get sbLoc
3108 int sswId_o{0}, sbLoc_o{0}, slbId_o{0};
3109 bool found = getHiPtIds(state, rdH, sswId_o, sbLoc_o, slbId_o);
3110 if (!found) {
3111 continue;
3112 }
3113
3114 // Get subMatrix
3115 int slbsubMatrix = 0;
3116 std::array<int, 2> bitpos_o{};
3117 getBitPosOutStrip(rdH, slbsubMatrix, bitpos_o);
3118
3119 // Get trackletId
3120 int trackletIdStrip = 2 * sbLoc_o + slbsubMatrix;
3121
3122 // Compare trackletIds
3123 if (trackletIdStrip != trackletIdStripFirst &&
3124 trackletIdStrip != trackletIdStripSecond &&
3125 trackletIdStrip != trackletIdStripThird) {
3126 continue;
3127 }
3128
3129 // The third candidate is used only if any corresponding HiPt Strip
3130 // is found so far.
3131 if (exist_hipt_s && trackletIdStrip == trackletIdStripThird) {
3132 continue;
3133 }
3134
3135 // getRDOHighPtIDfromSimHighPtID overwrites index, chip and hitId.
3136 int index_w_tmp = index_w;
3137 int chip_w_tmp = chip_w;
3138 int hitId_w_tmp = hitId_w;
3139 // Get RDO HighPt ID from SimHighPtID for wire
3141 false, // false for endcap
3142 false, // wire
3143 index_w_tmp, chip_w_tmp, hitId_w_tmp);
3144 if (!found) {
3146 "Failed to get RDOHighPtID from SimHighPtID for Wire");
3147 continue;
3148 }
3149
3150 // RDO High Pt ID of Strip
3151 int chip_s = static_cast<int>(rdH.chip());
3152 int hitId_s = static_cast<int>(rdH.hitId());
3153 int hsub_s = static_cast<int>(rdH.hsub());
3154
3155 int roi = 0;
3156 found = state.cabling->getROINumberfromHighPtID(
3157 roi,
3158 false, // false for Endcap
3159 index_w_tmp, // hpb_wire (not used)
3160 chip_w_tmp, // chip_wire
3161 hitId_w_tmp, // hitId_wire
3162 sub_w, // sub_wire
3163 chip_s, // chip_strip (not used)
3164 hitId_s, // hitId_strip
3165 hsub_s); // sub_strip
3166 if (!found) {
3168 "Failed to get ROINumber from HighPtID for Strip");
3169 continue;
3170 }
3171
3172 if (roi == rd.roi()) {
3173 sbLoc = sbLoc_o;
3174 exist_hipt_s = true;
3175 if (trackletIdStrip == trackletIdStripFirst) {
3176 break; // If the first candidate is found, exit from this
3177 // for loop
3178 }
3179 }
3180 }
3181 }
3182
3183 return exist_hipt_s;
3184}
3185
3187 const TgcRawData& rd, int& sbLoc, const TgcRdo* rdoColl, const int index_w,
3188 const int chip_w, const int hitId_w, const int sub_w) const {
3189
3190 bool exist_tracklet_s = false;
3191
3192 // Get trackletIds of three candidates
3193 int trackletIdStripFirst{-1}, trackletIdStripSecond{-1},
3194 trackletIdStripThird{-1};
3196 static_cast<int>(rd.roi()), trackletIdStripFirst, trackletIdStripSecond,
3197 trackletIdStripThird);
3198
3199 // Loop over all Tracklet Strip to find an associated one
3200 for (const TgcRawData* rdS0 : *rdoColl) {
3201
3202 // conversion for Run3
3203 uint16_t tmprodId{0}, tmpsector{0};
3204 convertToRun2(rdS0, tmprodId, tmpsector);
3205 const TgcRawData rdS(rdS0->bcTag(), rdS0->subDetectorId(), tmprodId,
3206 rdS0->sswId(), rdS0->slbId(), rdS0->l1Id(),
3207 rdS0->bcId(), rdS0->slbType(), rdS0->delta(),
3208 rdS0->segment(), rdS0->subMatrix(),
3209 rdS0->position());
3210
3211 bool isForward_s = (rdS.sswId() == 7); // Doublet, Forward
3212 if (isForward_s) {
3213 continue; // Chamber boundaries exist in endcap only
3214 }
3215
3216 if ((rdS.type() == TgcRawData::TYPE_TRACKLET) &&
3218 (rdS.bcTag() == rd.bcTag()) &&
3219 (rdS.subDetectorId() == rd.subDetectorId()) &&
3220 (rdS.rodId() == rd.rodId()) &&
3221 (rdS.sswId() - 3 ==
3222 rd.sector()) // SSW3: M3-EC phi0, SSW4: M3-EC phi1, SSW5: M3-EC
3223 // phi2, SSW6: M3-EC phi3
3224 ) {
3225
3226 // Compare trackletIds
3227 int trackletIdStrip = static_cast<int>(
3228 2 * rdS.slbId() +
3229 rdS.subMatrix()); // trackletId of Tracklet Strip
3230 if (trackletIdStrip != trackletIdStripFirst &&
3231 trackletIdStrip != trackletIdStripSecond &&
3232 trackletIdStrip != trackletIdStripThird) {
3233 continue;
3234 }
3235
3236 // The third candidate is used only if any corresponding Tracklet
3237 // Strip is found so far.
3238 if (exist_tracklet_s && trackletIdStrip == trackletIdStripThird) {
3239 continue;
3240 }
3241
3242 Identifier offlineId;
3243 bool found =
3245 offlineId, rdS.subDetectorId(), rdS.rodId(), rdS.sswId(),
3246 rdS.slbId(), rdS.subMatrix(), rdS.position(), false);
3247 if (!found) {
3249 "Failed to get OfflineID from LowPtCoincidenceID for "
3250 "Strip");
3251 continue;
3252 }
3253
3254 std::array<int, 7> i{};
3255 std::array<bool, 2> b{};
3256 found = state.cabling->getHighPtIDfromOfflineID(
3257 offlineId, i[0], i[1], i[2], b[0], b[1], i[3], i[4], i[5],
3258 i[6]);
3259 // i[0] subDetectorID, i[1] rodID, i[2] sectorInReadout, b[0]
3260 // isStrip, b[1] isForward, i[3] hpb, i[4] chip, i[5] hitID, i[6]
3261 // pos
3262
3263 if (!found) {
3265 "Failed to get HighPtID from OfflineID for Strip");
3266 continue;
3267 }
3268
3269 // getRDOHighPtIDfromSimHighPtID overwrites index, chip and hitId.
3270 int index_w_tmp = index_w;
3271 int chip_w_tmp = chip_w;
3272 int hitId_w_tmp = hitId_w;
3274 rd.isForward(), // false for endcap
3275 false, // wire
3276 index_w_tmp, // hpb-index
3277 chip_w_tmp, // chip-chip
3278 hitId_w_tmp); // hitID-hitId
3279 if (!found) {
3281 "Failed to get RDOHighPtID from SimHighPtID for Wire");
3282 continue;
3283 }
3284
3286 rd.isForward(), // false for endcap
3287 true, // strip
3288 i[3], // hpb-index
3289 i[4], // chip-chip
3290 i[5]); // hitID-hitId
3291 if (!found) {
3293 "Failed to get RDOHighPtID from SimHighPtID for Strip");
3294 continue;
3295 }
3296
3297 int roi = 0;
3298 found = state.cabling->getROINumberfromHighPtID(
3299 roi,
3300 rd.isForward(), // false for endcap
3301 index_w_tmp, // hpb_wire (not used)
3302 chip_w_tmp, // chip_wire
3303 hitId_w_tmp, // hitId_wire
3304 sub_w, // sub_wire
3305 i[4], // chip_strip (not used)
3306 i[5], // hitId_strip
3307 i[6]); // sub_strip
3308 if (!found) {
3310 "Failed to get ROINumber from HighPtID for Strip");
3311 continue;
3312 }
3313
3314 if (roi == rd.roi()) {
3315 sbLoc = rdS.slbId();
3316 exist_tracklet_s = true;
3317 if (trackletIdStrip == trackletIdStripFirst) {
3318 break; // If the first candidate is found, exit from this
3319 // for loop
3320 }
3321 }
3322 }
3323 }
3324
3325 return exist_tracklet_s;
3326}
3327
3329 const int roi, int& trackletIdStripFirst, int& trackletIdStripSecond,
3330 int& trackletIdStripThird) {
3331 constexpr int T9SscMax = 2; // SSC 0 to SSC 2
3332 constexpr int T8SscMax = 4; // SSC 3 to SSC 4
3333 constexpr int T7SscMax = 6; // SSC 5 to SSC 6
3334 constexpr int T6SscMax = 12; // SSC 7 to SSC12
3335 constexpr int T5SscMax = 18; // SSC13 to SSC18
3336
3337 constexpr int T9Offset = 32 + 0;
3338 constexpr int T8Offset = 32 + 2;
3339 constexpr int T7Offset = 32 + 4;
3340 constexpr int T6Offset = 32 + 6;
3341 constexpr int T5Offset = 32 + 8;
3342
3343 // ROI : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
3344 // SSC : 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 ...
3345 // Half SSC: 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ...
3346 int ssc = (roi + 4) / 8;
3347 int halfSsc = (roi % 4) / 2;
3348
3349 if (ssc < T9SscMax) { // SSC 0 to SSC 1
3350 trackletIdStripFirst = T9Offset + halfSsc; // T9
3351 trackletIdStripSecond = -1;
3352 trackletIdStripThird = -1;
3353 } else if (ssc == T9SscMax) { // SSC 2 (boundary)
3354 trackletIdStripFirst = T8Offset + halfSsc; // T8
3355 trackletIdStripSecond = T9Offset + halfSsc; // T9
3356 trackletIdStripThird = -1;
3357 } else if (ssc < T8SscMax) { // SSC 3
3358 trackletIdStripFirst = T8Offset + halfSsc; // T8
3359 trackletIdStripSecond = -1;
3360 trackletIdStripThird = -1;
3361 } else if (ssc == T8SscMax) { // SSC 4 (boundary)
3362 trackletIdStripFirst = T7Offset + halfSsc; // T7
3363 trackletIdStripSecond = T8Offset + halfSsc; // T8
3364 trackletIdStripThird = -1;
3365 } else if (ssc < T7SscMax) { // SSC 5
3366 trackletIdStripFirst = T7Offset + halfSsc; // T7
3367 trackletIdStripSecond = -1;
3368 trackletIdStripThird = -1;
3369 } else if (ssc == T7SscMax) { // SSC 6 (boundary)
3370 trackletIdStripFirst = T6Offset + halfSsc; // T6
3371 trackletIdStripSecond = T7Offset + halfSsc; // T7
3372 trackletIdStripThird =
3373 T5Offset + halfSsc; // T5, HiPt Endcap Strip board bug
3374 } else if (ssc < T6SscMax) { // SSC 7 to SSC11
3375 trackletIdStripFirst = T6Offset + halfSsc; // T6
3376 trackletIdStripSecond =
3377 T5Offset + halfSsc; // T5, HiPt Endcap Strip board bug
3378 trackletIdStripThird = -1;
3379 } else if (ssc == T6SscMax) { // SSC12 (boundary)
3380 trackletIdStripFirst = T6Offset + halfSsc; // T6
3381 trackletIdStripSecond = T5Offset + halfSsc; // T5
3382 trackletIdStripThird = -1;
3383 } else if (ssc <= T5SscMax) { // SSC13 to SSC18
3384 trackletIdStripFirst = T5Offset + halfSsc; // T5
3385 trackletIdStripSecond =
3386 T6Offset + halfSsc; // T6, HiPt Endcap Strip board bug
3387 trackletIdStripThird = -1;
3388 } else {
3389 trackletIdStripFirst = -1;
3390 trackletIdStripSecond = -1;
3391 trackletIdStripThird = -1;
3392 }
3393}
3394
3395
3396
3398 const MuonGM::TgcReadoutElement* readout, const Identifier identify,
3399 const double eta, const double phi) {
3400 if (!readout) {
3401 return Amg::Vector2D::Zero();
3402 }
3403
3404 // Obtain the local coordinate by the secant method
3405 constexpr double length = 100.; // 100 mm
3406 constexpr unsigned int nRep = 10; // 10 repetitions
3407 constexpr double dRAccuracy = 1.0E-20; // recuqired dR accuracy
3408 constexpr double maxLocR = 10000.; // 10 m
3409
3410 double locX = 0.;
3411 double locY = 0.;
3412 for (unsigned int iRep = 0; iRep < nRep; iRep++) {
3413 Amg::Vector2D loc_hitPos_c(locX, locY); // center or current position
3414 Amg::Vector3D tmp_glob_hitPos_c{Amg::Vector3D::Zero()};
3415 readout->surface(identify).localToGlobal(
3416 loc_hitPos_c, tmp_glob_hitPos_c, tmp_glob_hitPos_c);
3417 const Amg::Vector3D& glob_hitPos_c = tmp_glob_hitPos_c;
3418
3419 double glob_eta_c = glob_hitPos_c.eta();
3420 double glob_phi_c = glob_hitPos_c.phi();
3421
3422 Amg::Vector2D vector{eta - glob_eta_c, deltaPhi(phi, glob_phi_c)};
3423
3424 double dR = std::hypot(vector[0], vector[1]);
3425 if (dR < dRAccuracy) {
3426 break;
3427 }
3428
3429 Amg::Vector2D loc_hitPos_w(
3430 locX + length,
3431 locY); // slightly shifted position in the wire direction
3432 Amg::Vector2D loc_hitPos_s(
3433 locX,
3434 locY + length); // slightly shifted position in the strip direction
3435 Amg::Vector3D tmp_glob_hitPos_w{Amg::Vector3D::Zero()};
3436 readout->surface(identify).localToGlobal(
3437 loc_hitPos_w, tmp_glob_hitPos_w, tmp_glob_hitPos_w);
3438 const Amg::Vector3D& glob_hitPos_w = tmp_glob_hitPos_w;
3439 Amg::Vector3D tmp_glob_hitPos_s{Amg::Vector3D::Zero()};
3440 readout->surface(identify).localToGlobal(
3441 loc_hitPos_s, tmp_glob_hitPos_s, tmp_glob_hitPos_s);
3442 const Amg::Vector3D& glob_hitPos_s = tmp_glob_hitPos_s;
3443
3444 AmgSymMatrix(2) matrix{AmgSymMatrix(2)::Identity()};
3445 matrix(0, 0) = glob_hitPos_w.eta() - glob_eta_c;
3446 matrix(1, 0) = deltaPhi(glob_hitPos_w.phi(), glob_phi_c);
3447 matrix(0, 1) = glob_hitPos_s.eta() - glob_eta_c;
3448 matrix(1, 1) = deltaPhi(glob_hitPos_s.phi(), glob_phi_c);
3449
3450 bool invertible = matrix.determinant();
3451 if (invertible) {
3452 Amg::MatrixX invertedMatrix = matrix.inverse();
3453 Amg::Vector2D solution = invertedMatrix * vector;
3454 locX += length * solution(0, 0);
3455 locY += length * solution(1, 0);
3456
3457 double locR = sqrt(locX * locX + locY * locY);
3458 if (locR > maxLocR) {
3459 locX *= maxLocR / locR;
3460 locY *= maxLocR / locR;
3461 }
3462 }
3463 }
3464
3465 return Amg::Vector2D(locX, locY);
3466}
3467
3469 0.1; // 0.1 mm
Scalar eta() const
pseudorapidity method
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
#define endmsg
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
Definition ArrayHelper.h:10
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
#define AmgSymMatrix(dim)
double length(const pvec &v)
const double width
unsigned bcTag(unsigned bcBitMap)
#define z
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
bool empty() const
return true if container is empty
size_t size() const
Duplicate of fullSize for backwards compatability.
This is a "hash" representation of an Identifier.
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Amg::Vector3D channelPos(const Identifier &id) const
Returns the position of the active channel (wireGang or strip)
double stripHighEdgeLocX(int gasGap, int strip, double radialPos) const
Returns the local X of the right edge of the strip at a given local radial position.
double gangShortWidth(int gasGap, int gang) const
Returns the length of the most bottom wire in the gang.
double stripWidth(int gasGap, int strip) const
Returns the width of a given strip in the gasGap i.
double stripLowEdgeLocX(int gasGap, int strip, double radialPos) const
Returns the local X of the left edge of the strip at a given local radial position.
double gangLongWidth(int gasGap, int gang) const
Returns the length of the most top wire in the gang.
double gangRadialLength(int gasGap, int gang) const
Returns the length of the wire gang along the radial direction [pitch x N_{wire}^{gang}...
virtual bool containsId(const Identifier &id) const override
int stationPhi(const Identifier &id) const
bool getOfflineIDfromHighPtID(Identifier &offlineID, const int subDetectorID, const int rodID, const int sectorInReadout, const bool isStrip, const bool isForward, const int hpb, const int chip, const int hitID, const int pos) const
bool getSLBIDfromReadoutID(int &phi, bool &isAside, bool &isEndcap, int &moduleType, int &id, const int subsectorID, const int rodID, const int sswID, const int sbLoc) const
bool getHighPtIDfromOfflineID(const Identifier &offlineID, int &subDetectorID, int &rodID, int &sectorInReadout, bool &isStrip, bool &isForward, int &hpb, int &chip, int &hitID, int &pos) const
bool getElementIDfromReadoutID(Identifier &elementID, const int subDetectorID, const int rodID, const int sswID, const int sbLoc, const int channelID, bool orChannel=false) const
bool getRDOHighPtIDfromSimHighPtID(const bool isForward, const bool isStrip, int &index, int &chip, int &hitId) const
bool getOfflineIDfromReadoutID(Identifier &offlineID, const int subDetectorID, const int rodID, const int sswID, const int sbLoc, const int channelID, bool orChannel=false) const
To be ported.
bool getSLIDfromReadoutID(int &phi, bool &isAside, bool &isEndcap, const int subsectorID, const int rodID, const int sswID, const int sbLoc) const
bool getReadoutIDfromOfflineID(const Identifier &offlineID, int &subDetectorID, int &rodID, int &sswID, int &sbLoc, int &channelID, bool adChannel=false) const
bool getHighPtIDfromROINumber(int roi, bool isForward, bool isStrip, int &hpb, int &chip, int &hitID, int &sub) const
bool getSimHighPtIDfromRDOHighPtID(const bool isForward, const bool isStrip, int &index, int &chip, int &hitId) const
bool getOfflineIDfromLowPtCoincidenceID(Identifier &offlineID, const int subDetectorID, const int rodID, const int sswID, const int sbLoc, const int block, const int pos, bool middle=false) const
bool getROINumberfromHighPtID(int &roi, bool isForward, int hpb_wire, int chip_wire, int hitId_wire, int sub_wire, int chip_strip, int hitId_strip, int sub_strip) const
bool getSLIDfromSReadoutID(int &phi, bool &isAside, const int subsectorID, const int srodID, const int sector, const bool forward) const
bool isOredChannel(const int subDetectorID, const int rodID, const int sswID, const int sbLoc, const int channelID) const
To be ported.
bool getReadoutIDfromElementID(const Identifier &elementID, int &subdetectorID, int &rodID) const
static constexpr uint32_t INNER_NSW_ID_BITSHIFT
static constexpr uint32_t INNER_TILE_MODULE_BITSHIFT
Bit info in int inner for the Tile inner-coincidence.
static constexpr uint32_t INNER_NSW_PHIRES_BITSHIFT
static constexpr uint32_t INNER_EIFI_CID_BITSHIFT
static constexpr uint32_t INNER_RPC_BCID_BITSHIFT
static constexpr uint32_t INNER_RPC_ETA_BITSHIFT
Bit info in int inner for the RPC inner-coincidence.
static constexpr uint32_t INNER_EIFI_EI_BITSHIFT
Bit info in int inner for the EI/FI inner-coincidence.
static constexpr uint32_t INNER_RPC_PHI_BITSHIFT
static constexpr uint32_t INNER_RPC_DPHI_BITSHIFT
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
static constexpr uint32_t INNER_NSW_PHI_BITSHIFT
static constexpr uint32_t INNER_EIFI_FI_BITSHIFT
static constexpr uint32_t INNER_RPC_FLAG_BITSHIFT
static constexpr uint32_t INNER_NSW_BCID_BITSHIFT
static constexpr uint32_t INNER_RPC_DETA_BITSHIFT
static constexpr uint32_t INNER_NSW_R_BITSHIFT
Bit info in int inner for the NSW inner-coincidence.
static constexpr uint32_t INNER_TILE_BCID_BITSHIFT
static constexpr uint32_t INNER_NSW_LOWRES_BITSHIFT
static constexpr uint32_t INNER_NSW_INPUT_BITSHIFT
static constexpr uint32_t INNER_NSW_DTHETA_BITSHIFT
Class to represent TGC measurements.
Definition TgcPrepData.h:32
void setBcBitMap(const uint16_t)
set the bcBitMap for this PRD
uint16_t getBcBitMap() const
Returns the bcBitMap of this PRD bit2 for Previous BC, bit1 for Current BC, bit0 for Next BC.
SG::WriteHandleKeyArray< Muon::TgcPrepDataContainer > m_outputprepdataKeys
void convertToRun2(const TgcRawData *rd, uint16_t &newrodId, uint16_t &newsector) const
SG::ReadCondHandleKey< Muon::TgcCablingMap > m_cablingKey
static void getEndcapStripCandidateTrackletIds(const int roi, int &trackletIdStripFirst, int &trackletIdStripSecond, int &trackletIdStripThird)
Get trackletIds of three Tracklet Strip candidates in the Endcap boudary.
Gaudi::Property< std::string > m_outputCoinCollectionLocation
TgcCoinData container key for current BC.
StatusCode decodeSL(State &state, const TgcRawData &rd, const TgcRdo *rdoColl) const
Decode RDO's of SectorLogic.
bool getPosAndIdWireIn(const std::array< const MuonGM::TgcReadoutElement *, 4 > &descriptor_i, const std::array< Identifier, 4 > &channelIdIn, const std::array< int, 4 > &gasGap_i, const std::array< int, 4 > &channel_i, double &width_i, double &hit_position_i, Amg::Vector2D &tmp_hitPos_i, Identifier &channelIdIn_tmp) const
Get position and offline ID of TGC1 wire for HiPt.
static Amg::Vector2D getSLLocalPosition(const MuonGM::TgcReadoutElement *readout, const Identifier, const double eta, const double phi)
Get SL local position.
static int getDeltaBeforeConvert(const TgcRawData &rd)
Get delta (sagitta) before converion for HiPt.
StatusCode transferData(ContType &container, std::vector< std::unique_ptr< CollType > > &&coll) const
virtual StatusCode finalize() override
Standard AthAlgTool finalize method.
Gaudi::Property< std::string > m_outputCollectionLocation
TgcPrepRawData container key for current BC.
static bool isBackwardBW(const TgcRawData &rd)
Check if a chamber in BigWheel is a backward chamber or a forward chamber.
bool isIncludedInChamberBoundary(const TgcRawData &rd) const
Check SL RDO is at the chamber boundary.
static void getBitPosOutWire(const TgcRawData &rd, int &slbsubMatrix, std::array< int, 2 > &bitpos_o)
Get bitPos etc of TGC3 wire for HiPt.
void getBitPosWire(const TgcRawData &rd, const int hitId_w, const int sub_w, int &subMatrix_w, std::array< int, 3 > &bitpos_w) const
Get bitPos etc of wire for SL.
SG::WriteHandleKeyArray< Muon::TgcCoinDataContainer > m_outputCoinKeys
Gaudi::Property< std::string > m_prdContainerCacheKeyStr
SG::ReadHandleKey< TgcRdoContainer > m_rdoContainerKey
SG::WriteHandleKey< xAOD::TgcStripContainer > m_xAODKey
bool getPosAndIdStripIn(const std::array< const MuonGM::TgcReadoutElement *, 4 > &descriptor_i, const std::array< Identifier, 4 > &channelIdIn, const std::array< int, 4 > &gasGap_i, const std::array< int, 4 > &channel_i, double &width_i, double &hit_position_i, Amg::Vector2D &tmp_hitPos_i, Identifier &channelIdIn_tmp, const bool isBackward, const bool isAside) const
Get position and offline ID of TGC1 strip for HiPt.
static int getRoiRow(const TgcRawData &rd)
Get ROI row from RDO.
StatusCode decodeInner(State &state, const TgcRawData &rd) const
Decode RDO's of Inner.
Gaudi::Property< bool > m_fillCoinData
Switch for the coincince decoding.
void getBitPosInStrip(const TgcRawData &rd, const int DeltaBeforeConvert, std::array< int, 4 > &bitpos_i, std::array< int, 4 > &slbchannel_i, int &sbLoc_i, int &sswId_i, const std::array< int, 2 > &bitpos_o, std::array< int, 2 > &slbchannel_o) const
Get bitPos etc of TGC1 strip for HiPt.
StatusCode setupState(const EventContext &ctx, State &state) const
bool getHiPtIds(const State &state, const TgcRawData &rd, int &sswId_o, int &sbLoc_o, int &slbId_o) const
Get ReadoutID of HiPt from RDOHighPtID.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
StatusCode decodeTrackletEIFI(State &state, const TgcRawData &rd) const
Decode RDO's of Tracklet EIFI.
bool getSLStripGeometry(const std::array< Identifier, 3 > &channelId_strip, const bool isBackWard, const bool isAside, double &width_strip, double &theta_strip) const
Get strip geometry (width, theta) for SL.
bool isOfflineIdOKForTgcReadoutElement(const MuonGM::TgcReadoutElement *descriptor, const Identifier channelId) const
Check offline ID is OK for TgcReadoutElement.
Gaudi::Property< bool > m_dropPrdsWithZeroWidth
Flag for dropping PRD's with zero widths.
static bool getRfromEtaZ(const double eta, const double z, double &r)
Get r from eta and z.
bool getSLWireGeometry(const std::array< Identifier, 3 > &channelId_wire, double &width_wire, double &r_wire, double &z_wire) const
Get wire geometry (width, r, z) for SL.
TgcCoinUpdateHandles m_coinContainerCacheKeys
Keys for the Coin cache containers, 3 needed for different BC.
virtual StatusCode initialize() override
Standard AthAlgTool initialize method.
Gaudi::Property< bool > m_show_warning_level_invalid_A09_SSW6_hit
Switch for error message disabling on one invalid channel in sector A09 seen in 2008 data,...
Gaudi::Property< std::string > m_coinContainerCacheKeyStr
StatusCode decodeHiPt(State &state, const TgcRawData &rd) const
Decode RDO's of HiPt.
StatusCode decodeHits(State &state, const TgcRawData &rd) const
Decode RDO's of Hit.
static bool getEtafromRZ(const double r, const double z, double &eta)
Get eta from r and z.
void getBitPosInWire(const TgcRawData &rd, const int DeltaBeforeConvert, std::array< int, 4 > &bitpos_i, std::array< int, 4 > &slbchannel_i, std::array< int, 4 > &slbId_in, std::array< int, 4 > &sbLoc_in, int &sswId_i, const std::array< int, 2 > &bitpos_o, std::array< int, 2 > &slbchannel_o, const int slbId_o) const
Get bitPos etc of TGC1 wire for HiPt.
virtual StatusCode decode(const EventContext &ctx, const std::vector< IdentifierHash > &idVect) const override
Decode RDO to PRD A vector of IdentifierHash are passed in, and the data corresponding to this list (...
bool getPosAndIdWireOut(const std::array< const MuonGM::TgcReadoutElement *, 2 > &descriptor_o, const std::array< Identifier, 2 > &channelIdOut, const std::array< int, 2 > &gasGap_o, const std::array< int, 2 > &channel_o, double &width_o, double &hit_position_o, Amg::Vector2D &tmp_hitPos_o, Identifier &channelIdOut_tmp) const
Get position and offline ID of TGC3 wire for HiPt.
TgcPrdUpdateHandles m_prdContainerCacheKeys
Keys for the PRD cache containers, 4 needed for different BC.
Gaudi::Property< bool > m_decodeData
Switch for the decoding of TGC RDO into TgcPrepData.
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_muDetMgrKey
void selectDecoder(State &state, const TgcRawData &rd, const TgcRdo *rdoColl) const
Select decoder based on RDO type (Hit or Coincidence (Tracklet, HiPt and SL))
std::atomic< long > m_nHitRDOs
long to count the numbers of RDOs and PRDs
StatusCode decodeTracklet(State &state, const TgcRawData &rd) const
Decode RDO's of Tracklet.
static int getbitpos(int channel, TgcRawData::SlbType slbType)
Get bitpos from channel and SlbType.
bool getSLIds(const State &state, const bool isStrip, const TgcRawData &rd, std::array< Identifier, 3 > &channelId, int &index, int &chip, int &hitId, int &sub, int &sswId, int &sbLoc, int &subMatrix, std::array< int, 3 > &bitpos, const bool isBoundary=false, const TgcRdo *rdoColl=0, const int index_w=-1, const int chip_w=-1, const int hitId_w=-1, const int sub_w=-1) const
Get ReadoutID of SL from RDO.
static int getchannel(int bitpos, TgcRawData::SlbType slbType)
Get channel from bitpos and SlbType.
bool getTrackletInfo(const TgcRawData &rd, int &tmp_slbId, int &tmp_subMatrix, int &tmp_position) const
Retrieve slbId, subMatrix and position from Tracklet RDO.
bool getSbLocOfEndcapStripBoundaryFromHiPt(const State &state, const TgcRawData &rd, int &sbLoc, const TgcRdo *rdoColl, const int index_w, const int chip_w, const int hitId_w, const int sub_w) const
Get strip sbLoc of Endcap chamber boundary from HiPt Strip.
static void getBitPosStrip(const int hitId_s, const int sub_s, int &subMatrix_s, std::array< int, 3 > &bitpos_s)
Get bitPos etc of strip for SL.
virtual StatusCode provideEmptyContainer(const EventContext &ctx) const override
static constexpr int NBC_HIT
The number of recorded Bunch Crossings (BCs) FOR HITS is 3 (Previous, Current, and Next BCs)
static const double s_cutDropPrdsWithZeroWidth
Cut value for zero widths.
bool getSbLocOfEndcapStripBoundaryFromTracklet(const State &state, const TgcRawData &rd, int &sbLoc, const TgcRdo *rdoColl, const int index_w, const int chip_w, const int hitId_w, const int sub_w) const
Get strip sbLoc of Endcap chamber boundary from Tracklet Strip.
static void getBitPosOutStrip(const TgcRawData &rd, int &slbsubMatrix, std::array< int, 2 > &bitpos_o)
Get bitPos etc of TGC3 strip for HiPt.
bool getPosAndIdStripOut(const std::array< const MuonGM::TgcReadoutElement *, 2 > &descriptor_o, const std::array< Identifier, 2 > &channelIdOut, const std::array< int, 2 > &gasGap_o, const std::array< int, 2 > &channel_o, double &width_o, double &hit_position_o, Amg::Vector2D &tmp_hitPos_o, Identifier &channelIdOut_tmp, const bool isBackward, const bool isAside) const
Get position and offline ID of TGC3 strip for HiPt.
const_pointer_type cptr()
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
@ BC_UNDEFINED
Definition TgcDigit.h:37
@ BC_NEXT
Definition TgcDigit.h:37
@ BC_CURRENT
Definition TgcDigit.h:37
@ BC_PREVIOUS
Definition TgcDigit.h:37
@ BC_NEXTNEXT
Definition TgcDigit.h:37
int channel(const Identifier &id) const override
int gasGap(const Identifier &id) const override
get the hashes
int isStrip(const Identifier &id) const
isStrip corresponds to measuresPhi
An unit object of TGC ROD output.
Definition TgcRawData.h:23
uint16_t nswlowres() const
Definition TgcRawData.h:413
uint16_t hsub() const
Definition TgcRawData.h:349
uint16_t sswId() const
Definition TgcRawData.h:272
bool isStrip() const
Definition TgcRawData.h:353
@ SLB_TYPE_TRIPLET_WIRE
Definition TgcRawData.h:34
@ SLB_TYPE_INNER_WIRE
Definition TgcRawData.h:36
@ SLB_TYPE_TRIPLET_STRIP
Definition TgcRawData.h:35
@ SLB_TYPE_INNER_STRIP
Definition TgcRawData.h:37
@ SLB_TYPE_DOUBLET_STRIP
Definition TgcRawData.h:33
@ SLB_TYPE_DOUBLET_WIRE
Definition TgcRawData.h:32
uint16_t chip() const
Definition TgcRawData.h:337
uint16_t index() const
Definition TgcRawData.h:309
int16_t delta() const
Definition TgcRawData.h:317
uint16_t position() const
Definition TgcRawData.h:313
uint16_t subMatrix() const
Definition TgcRawData.h:329
uint16_t l1Id() const
Definition TgcRawData.h:255
uint16_t innerflag() const
Definition TgcRawData.h:381
SlbType slbType() const
Definition TgcRawData.h:285
uint16_t bcId() const
Definition TgcRawData.h:259
bool isMuplus() const
Definition TgcRawData.h:361
bool isVeto() const
Definition TgcRawData.h:373
DataType type() const
Definition TgcRawData.h:280
uint16_t coinflag() const
Definition TgcRawData.h:385
static constexpr uint32_t RPC_FLAG_BIT
Definition TgcRawData.h:223
uint16_t ei() const
Definition TgcRawData.h:441
uint16_t bitpos() const
Definition TgcRawData.h:293
static constexpr uint32_t RPC_BCID_BITSHIFT
Definition TgcRawData.h:226
uint16_t rpcdeta() const
Definition TgcRawData.h:433
uint16_t nswid() const
Definition TgcRawData.h:417
bool isCoincidence() const
Definition TgcRawData.h:237
uint16_t tmdbbcid() const
Definition TgcRawData.h:457
uint16_t rpcphi() const
Definition TgcRawData.h:425
static constexpr uint32_t NSW_INPUT_BIT
Definition TgcRawData.h:218
uint16_t fi() const
Definition TgcRawData.h:445
uint16_t bcTag() const
Definition TgcRawData.h:251
static constexpr uint32_t RPC_BCID_BIT
Definition TgcRawData.h:227
uint16_t nsweta() const
Definition TgcRawData.h:389
uint16_t nswcand() const
Definition TgcRawData.h:401
uint16_t nswphires() const
Definition TgcRawData.h:409
static constexpr uint32_t NSW_INPUT_BITSHIFT
Definition TgcRawData.h:217
uint16_t cid() const
Definition TgcRawData.h:449
uint16_t subDetectorId() const
Definition TgcRawData.h:264
uint16_t slbId() const
Definition TgcRawData.h:276
static constexpr uint32_t RPC_FLAG_BITSHIFT
Definition TgcRawData.h:222
uint16_t rodId() const
Definition TgcRawData.h:268
uint16_t rpceta() const
Definition TgcRawData.h:421
uint16_t tmdbmod() const
Definition TgcRawData.h:453
uint16_t nswdtheta() const
Definition TgcRawData.h:405
uint16_t sector() const
Definition TgcRawData.h:333
static constexpr uint32_t NSW_BCID_BIT
Definition TgcRawData.h:220
@ TYPE_INNER_EIFI
Definition TgcRawData.h:50
@ TYPE_INNER_TMDB
Definition TgcRawData.h:51
bool isHipt() const
Definition TgcRawData.h:341
uint16_t roi() const
Definition TgcRawData.h:377
static constexpr uint32_t NSW_BCID_BITSHIFT
Definition TgcRawData.h:219
uint16_t rpcflag() const
Definition TgcRawData.h:429
uint16_t rpcdphi() const
Definition TgcRawData.h:437
uint16_t hitId() const
Definition TgcRawData.h:345
bool isForward() const
Definition TgcRawData.h:289
uint16_t inner() const
Definition TgcRawData.h:321
uint16_t nswphi() const
Definition TgcRawData.h:393
uint16_t threshold() const
Definition TgcRawData.h:365
static uint16_t calculateOnlineId(uint16_t subDetectorId, uint16_t rodId)
Definition TgcRdo.cxx:60
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
Identifier identify() const
return the identifier
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
void setMeasuresPhi(uint8_t measPhi)
Set the measures phi flag of the measurement to true /false.
void setGasGap(uint8_t gapNum)
Set the gas gap number of the measurement [1-N].
void setChannelNumber(uint16_t chan)
Set the strip or wire group number of the measurement.
void setBcBitMap(uint16_t)
Set the bunch crossing-id map.
uint8_t measuresPhi() const
Does the object belong to an eta or a phi measurement (si /no)
void setMeasurement(const DetectorIDHashType idHash, MeasVector< N > locPos, MeasMatrix< N > locCov)
Sets IdentifierHash, local position and local covariance of the measurement.
void setIdentifier(const DetectorIdentType measId)
Sets the full Identifier of the measurement.
int r
Definition globals.cxx:22
std::vector< std::string > veto
these patterns are anded
Definition listroot.cxx:191
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
Definition index.py:1
setRcore setEtHad setFside pt
Eigen::Matrix< float, N, N > MeasMatrix
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
TgcStrip_v1 TgcStrip
Definition TgcStripFwd.h:9
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
setWord1 uint16_t
std::array< TgcCoinDataContainer *, NBC_TRIG > tgcCoinDataContainer
TgcCoinData (coincidence PRD) containers.
std::array< TempCoinDataContainer, NBC_TRIG > tgcCoinDataCollections
std::array< TgcPrepDataContainer *, NBC_HIT+1 > tgcPrepDataContainer
TgcPrepRawData (hit PRD) containers.
const MuonGM::MuonDetectorManager * muDetMgr
std::array< TempPrepDataContainer, NBC_HIT+1 > tgcPrepDataCollections
MsgStream & msg
Definition testRead.cxx:32