ATLAS Offline Software
Loading...
Searching...
No Matches
TgcRdoToTgcDigit.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TgcRdoToTgcDigit.h"
6
7
9 ATH_CHECK(m_idHelperSvc.retrieve());
11 ATH_CHECK(m_tgcRdoKey.initialize());
12 ATH_CHECK(m_tgcDigitKey.initialize());
13 ATH_CHECK(m_cablingKey.initialize());
14 return StatusCode::SUCCESS;
15}
16
17StatusCode TgcRdoToTgcDigit::execute(const EventContext& ctx) const {
18 ATH_MSG_DEBUG("in execute()");
19 // retrieve the collection of RDO
20 const TgcRdoContainer* rdoContainer{};
21 ATH_CHECK(SG::get(rdoContainer, m_tgcRdoKey, ctx));
22 ATH_MSG_DEBUG("Retrieved " << rdoContainer->size() << " TGC RDOs.");
23
24 SG::WriteHandle wh_tgcDigit(m_tgcDigitKey, ctx);
25 ATH_CHECK(wh_tgcDigit.record(std::make_unique<TgcDigitContainer>(m_idHelperSvc->tgcIdHelper().module_hash_max())));
26 ATH_MSG_DEBUG("Decoding TGC RDO into TGC Digit");
27
28
29 TmpDigitContainer_t outDigitContainer{};
30 for (const TgcRdo* rdoColl : *rdoContainer) {
31 if (!rdoColl->empty()) {
32 ATH_CHECK(decodeTgc(ctx, *rdoColl, outDigitContainer));
33 }
34 }
35 for (auto& coll : outDigitContainer){
36 if (!coll) {
37 continue;
38 }
39 const IdentifierHash hash = coll->identifierHash();
40 ATH_CHECK(wh_tgcDigit->addCollection(coll.release(), hash));
41 }
42
43 return StatusCode::SUCCESS;
44}
45
46StatusCode TgcRdoToTgcDigit::decodeTgc(const EventContext& ctx,
47 const TgcRdo& rdoColl,
48 TmpDigitContainer_t& outDigitContainer) const {
49
50 const Muon::TgcCablingMap* cabling{nullptr};
51 ATH_CHECK(SG::get(cabling, m_cablingKey, ctx));
52 ATH_MSG_DEBUG("Number of RawData in this rdo " << rdoColl.size());
53 // for each Rdo, loop over RawData, converter RawData to digit
54 // retrieve/create digit collection, and insert digit into collection
55
56 std::map<std::vector<uint16_t>, uint16_t> stripMap;
57
58 // TGC2 Endcap Strip OR channel treatement preparation start
59 // Signals are ORed as follows:
60 // |stationEta|=5, T9, E1 - slbId=16, bit0 of stripSlbBits in this code
61 // /
62 // |stationEta|=4, T8, E2 - slbId=17, bit1 of stripSlbBits in this code
63 // /
64 // |stationEta|=3, T7, E3 - slbId=18, bit2 of stripSlbBits in this code
65 // /
66 // |stationEta|=2, T6, E4 - slbId=19, bit3 of stripSlbBits in this code
67 // /
68 // |stationEta|=1, T4, E5 - slbId=20, bit4 of stripSlbBits in this code
69 for (const TgcRawData* rawData : rdoColl) {
70 if (rawData->isCoincidence()) continue; // Require hits
71 if (rawData->slbType() != TgcRawData::SLB_TYPE_DOUBLET_STRIP) continue; // Require TGC2 or TGC3
72 if (rawData->sswId() == 7) continue; // Exclude Forward
73 if (rawData->bitpos() < 112 || rawData->bitpos() > 199) continue; // Require C, D-input
74
75 std::vector<uint16_t> stripId(5, 0);
76 stripId.at(0) = rawData->subDetectorId();
77 stripId.at(1) = rawData->rodId();
78 stripId.at(2) = rawData->sswId();
79 stripId.at(3) = rawData->bitpos();
80 stripId.at(4) = rawData->bcTag();
81 uint16_t stripSlbBits = 0x1 << (rawData->slbId() - 16);
82 std::map<std::vector<uint16_t>, uint16_t>::iterator itMap = stripMap.find(stripId); // Find correspond channel
83 if (itMap == stripMap.end()) { // This is new one
84 stripMap.insert(std::map<std::vector<uint16_t>, uint16_t>::value_type(stripId, stripSlbBits));
85 } else { // This already exists
86 itMap->second |= stripSlbBits;
87 }
88 }
89 // Covert to original hit patterns
90 for (auto& jtPair : stripMap) {
91 if (jtPair.second <= 31) {
92 // x : 5-bit variable
93 // f(x) : OR function above, Digit->RDO conversion
94 // g(x) : originalHitBits which satisfies f(g(f(x))) = f(x), RDO->Digit conversion
95 static constexpr std::array<uint16_t, 32> originalHitBits{// 0 1 2 3 4 5 6 7
96 0, 1, 0, 3, 0, 0, 4, 7,
97 // 8 9 10 11 12 13 14 15
98 0, 0, 0, 0, 8, 9, 12, 15,
99 // 16 17 18 19 20 21 22 23
100 0, 0, 0, 0, 0, 0, 0, 0,
101 // 24 25 26 27 28 29 30 31
102 16, 17, 0, 19, 24, 25, 28, 31};
103 jtPair.second = originalHitBits[jtPair.second];
104 } else {
105 jtPair.second = 0;
106 }
107 }
108 // TGC2 Endcap Strip OR channel treatement preparation end
109
110 for (const TgcRawData* rawData : rdoColl) {
111 // check Hit or Coincidence
112 if (rawData->isCoincidence()) continue;
113
114 // TGC2 Endcap Strip OR channel treatement start
115 if (rawData->slbType() == TgcRawData::SLB_TYPE_DOUBLET_STRIP && // Require TGC2 or TGC3
116 rawData->sswId() != 7 && // Exclude Forward
117 rawData->bitpos() >= 112 && rawData->bitpos() <= 199 // Require C, D-input
118 ) {
119 std::vector<uint16_t> stripId(5, 0);
120 stripId.at(0) = rawData->subDetectorId();
121 stripId.at(1) = rawData->rodId();
122 stripId.at(2) = rawData->sswId();
123 stripId.at(3) = rawData->bitpos();
124 stripId.at(4) = rawData->bcTag();
125 std::map<std::vector<uint16_t>, uint16_t>::iterator itMap = stripMap.find(stripId); // Find correspond hit
126 if (itMap != stripMap.end()) {
127 uint16_t stripSlbBits = 0x1 << (rawData->slbId() - 16);
128 if (!(itMap->second & stripSlbBits)) continue; // This hit is additional.
129 }
130 }
131 // TGC2 Endcap Strip OR channel treatement end
132
133 // repeat two times for ORed channel
134 for (int iOr = 0; iOr < 2; ++iOr) {
135 // TGC2 Endcap Strip OR channel is not converted.
136 if (iOr && rawData->slbType() == TgcRawData::SLB_TYPE_DOUBLET_STRIP) continue;
137
138 bool orFlag = false;
139
140 // check if this channel has ORed partner only when 2nd time
141 if (iOr != 0) {
142 const bool o_found = cabling->isOredChannel(rawData->subDetectorId(),
143 rawData->rodId(),
144 rawData->sswId(),
145 rawData->slbId(),
146 rawData->bitpos());
147 // set OR flag
148 if (o_found)
149 orFlag = true;
150 else
151 continue;
152 }
153
154 // get element ID
155 Identifier elementId;
156 const bool e_found = cabling->getElementIDfromReadoutID(elementId, rawData->subDetectorId(), rawData->rodId(),
157 rawData->sswId(), rawData->slbId(), rawData->bitpos(),
158 orFlag);
159
160 if (!e_found) {
161 bool show_warning_level = true;
162
163 /* One invalid channel in TGC sector A09:
164 sub=103 rod=9 ssw=6 slb=20 bitpos=151 orFlag=0
165 was always seen in 2008 data, at least run 79772 - 91800.
166 bug #48828 */
167 if (rawData->subDetectorId() == 103 && rawData->rodId() == 9 && rawData->sswId() == 6 && rawData->slbId() == 20 &&
168 rawData->bitpos() == 151) {
170 }
171
172 if (show_warning_level || msgLvl(MSG::DEBUG)) {
173 ATH_MSG_WARNING("ElementID not found for "
174 << " sub=" << rawData->subDetectorId() << " rod=" << rawData->rodId() << " ssw=" << rawData->sswId()
175 << " slb=" << rawData->slbId() << " bitpos=" << rawData->bitpos() << " orFlag=" << orFlag);
176 }
177 continue;
178 }
179
180 // convert RawData to Digit
181 std::unique_ptr<TgcDigit> newDigit(m_tgcRdoDecoderTool->getDigit(ctx, *rawData, orFlag));
182
183 // check if converted correctly
184 if (!newDigit) continue;
185
186 // check new element or not
187
188 const IdentifierHash coll_hash = m_idHelperSvc->moduleHash(elementId);
189 if (coll_hash >= outDigitContainer.size()) {
190 outDigitContainer.resize(coll_hash +1u);
191 }
192 std::unique_ptr<TgcDigitCollection>& collection = outDigitContainer[coll_hash];
193 if (!collection) {
194 collection = std::make_unique<TgcDigitCollection>(m_idHelperSvc->chamberId(elementId),
195 coll_hash);
196 }
197
198 // check duplicate digits
199 if (!std::ranges::any_of(*collection, [&newDigit](const TgcDigit* digit){
200 return newDigit->identify() == digit->identify() && newDigit->bcTag() == digit->bcTag();
201 })) {
202 collection->push_back(std::move(newDigit));
203 }
204 }
205 }
206 return StatusCode::SUCCESS;
207}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool msgLvl(const MSG::Level lvl) const
size_type size() const noexcept
Returns the number of elements in the collection.
size_t size() const
Duplicate of fullSize for backwards compatability.
This is a "hash" representation of an Identifier.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
An unit object of TGC ROD output.
Definition TgcRawData.h:23
@ SLB_TYPE_DOUBLET_STRIP
Definition TgcRawData.h:33
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ToolHandle< Muon::ITGC_RDO_Decoder > m_tgcRdoDecoderTool
SG::WriteHandleKey< TgcDigitContainer > m_tgcDigitKey
SG::ReadHandleKey< TgcRdoContainer > m_tgcRdoKey
SG::ReadCondHandleKey< Muon::TgcCablingMap > m_cablingKey
Gaudi::Property< bool > m_show_warning_level_invalid_TGC_A09_SSW6_hit
virtual StatusCode execute(const EventContext &ctx) const override final
StatusCode decodeTgc(const EventContext &ctx, const TgcRdo &rdo, TmpDigitContainer_t &outDigits) const
std::vector< std::unique_ptr< TgcDigitCollection > > TmpDigitContainer_t
virtual StatusCode initialize() override final
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.