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_tgcCabling.retrieve());
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 SG::ReadHandle rdoContainer{m_tgcRdoKey, ctx};
21 ATH_CHECK(rdoContainer.isPresent());
22 ATH_MSG_DEBUG("Retrieved " << rdoContainer->size() << " TGC RDOs.");
23
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 Identifier oldElementId;
29
30 TgcRdoContainer::const_iterator tgcRDO = rdoContainer->begin();
31
32 for (; tgcRDO != rdoContainer->end(); ++tgcRDO) {
33 if (!(*tgcRDO)->empty()) { ATH_CHECK(this->decodeTgc(*tgcRDO, wh_tgcDigit.ptr(), oldElementId)); }
34 }
35
36 return StatusCode::SUCCESS;
37}
38
39StatusCode TgcRdoToTgcDigit::decodeTgc(const TgcRdo* rdoColl, TgcDigitContainer* tgcContainer, Identifier& oldElementId) const {
40 TgcDigitCollection* collection = nullptr;
41
42 const IdContext tgcContext = m_idHelperSvc->tgcIdHelper().module_context();
43
44 ATH_MSG_DEBUG("Number of RawData in this rdo " << rdoColl->size());
45 // for each Rdo, loop over RawData, converter RawData to digit
46 // retrieve/create digit collection, and insert digit into collection
47
48 std::map<std::vector<uint16_t>, uint16_t> stripMap;
49
50 // TGC2 Endcap Strip OR channel treatement preparation start
51 // Signals are ORed as follows:
52 // |stationEta|=5, T9, E1 - slbId=16, bit0 of stripSlbBits in this code
53 // /
54 // |stationEta|=4, T8, E2 - slbId=17, bit1 of stripSlbBits in this code
55 // /
56 // |stationEta|=3, T7, E3 - slbId=18, bit2 of stripSlbBits in this code
57 // /
58 // |stationEta|=2, T6, E4 - slbId=19, bit3 of stripSlbBits in this code
59 // /
60 // |stationEta|=1, T4, E5 - slbId=20, bit4 of stripSlbBits in this code
61 for (const TgcRawData* rawData : *rdoColl) {
62 if (rawData->isCoincidence()) continue; // Require hits
63 if (rawData->slbType() != TgcRawData::SLB_TYPE_DOUBLET_STRIP) continue; // Require TGC2 or TGC3
64 if (rawData->sswId() == 7) continue; // Exclude Forward
65 if (rawData->bitpos() < 112 || rawData->bitpos() > 199) continue; // Require C, D-input
66
67 std::vector<uint16_t> stripId(5, 0);
68 stripId.at(0) = rawData->subDetectorId();
69 stripId.at(1) = rawData->rodId();
70 stripId.at(2) = rawData->sswId();
71 stripId.at(3) = rawData->bitpos();
72 stripId.at(4) = rawData->bcTag();
73 uint16_t stripSlbBits = 0x1 << (rawData->slbId() - 16);
74 std::map<std::vector<uint16_t>, uint16_t>::iterator itMap = stripMap.find(stripId); // Find correspond channel
75 if (itMap == stripMap.end()) { // This is new one
76 stripMap.insert(std::map<std::vector<uint16_t>, uint16_t>::value_type(stripId, stripSlbBits));
77 } else { // This already exists
78 itMap->second |= stripSlbBits;
79 }
80 }
81 // Covert to original hit patterns
82 for (auto& jtPair : stripMap) {
83 if (jtPair.second <= 31) {
84 // x : 5-bit variable
85 // f(x) : OR function above, Digit->RDO conversion
86 // g(x) : originalHitBits which satisfies f(g(f(x))) = f(x), RDO->Digit conversion
87 static const uint16_t originalHitBits[32] = {// 0 1 2 3 4 5 6 7
88 0, 1, 0, 3, 0, 0, 4, 7,
89 // 8 9 10 11 12 13 14 15
90 0, 0, 0, 0, 8, 9, 12, 15,
91 // 16 17 18 19 20 21 22 23
92 0, 0, 0, 0, 0, 0, 0, 0,
93 // 24 25 26 27 28 29 30 31
94 16, 17, 0, 19, 24, 25, 28, 31};
95 jtPair.second = originalHitBits[jtPair.second];
96 } else {
97 jtPair.second = 0;
98 }
99 }
100 // TGC2 Endcap Strip OR channel treatement preparation end
101
102 for (const TgcRawData* rawData : *rdoColl) {
103 // check Hit or Coincidence
104 if (rawData->isCoincidence()) continue;
105
106 // TGC2 Endcap Strip OR channel treatement start
107 if (rawData->slbType() == TgcRawData::SLB_TYPE_DOUBLET_STRIP && // Require TGC2 or TGC3
108 rawData->sswId() != 7 && // Exclude Forward
109 rawData->bitpos() >= 112 && rawData->bitpos() <= 199 // Require C, D-input
110 ) {
111 std::vector<uint16_t> stripId(5, 0);
112 stripId.at(0) = rawData->subDetectorId();
113 stripId.at(1) = rawData->rodId();
114 stripId.at(2) = rawData->sswId();
115 stripId.at(3) = rawData->bitpos();
116 stripId.at(4) = rawData->bcTag();
117 std::map<std::vector<uint16_t>, uint16_t>::iterator itMap = stripMap.find(stripId); // Find correspond hit
118 if (itMap != stripMap.end()) {
119 uint16_t stripSlbBits = 0x1 << (rawData->slbId() - 16);
120 if (!(itMap->second & stripSlbBits)) continue; // This hit is additional.
121 }
122 }
123 // TGC2 Endcap Strip OR channel treatement end
124
125 // repeat two times for ORed channel
126 for (int iOr = 0; iOr < 2; ++iOr) {
127 // TGC2 Endcap Strip OR channel is not converted.
128 if (iOr && rawData->slbType() == TgcRawData::SLB_TYPE_DOUBLET_STRIP) continue;
129
130 bool orFlag = false;
131
132 // check if this channel has ORed partner only when 2nd time
133 if (iOr != 0) {
134 const bool o_found = m_tgcCabling->isOredChannel(rawData->subDetectorId(), rawData->rodId(), rawData->sswId(),
135 rawData->slbId(), rawData->bitpos());
136 // set OR flag
137 if (o_found)
138 orFlag = true;
139 else
140 continue;
141 }
142
143 // get element ID
144 Identifier elementId;
145 const bool e_found = m_tgcCabling->getElementIDfromReadoutID(elementId, rawData->subDetectorId(), rawData->rodId(),
146 rawData->sswId(), rawData->slbId(), rawData->bitpos(), orFlag);
147
148 if (!e_found) {
149 bool show_warning_level = true;
150
151 /* One invalid channel in TGC sector A09:
152 sub=103 rod=9 ssw=6 slb=20 bitpos=151 orFlag=0
153 was always seen in 2008 data, at least run 79772 - 91800.
154 bug #48828 */
155 if (rawData->subDetectorId() == 103 && rawData->rodId() == 9 && rawData->sswId() == 6 && rawData->slbId() == 20 &&
156 rawData->bitpos() == 151) {
158 }
159
160 if (show_warning_level || msgLvl(MSG::DEBUG)) {
161 ATH_MSG_WARNING("ElementID not found for "
162 << " sub=" << rawData->subDetectorId() << " rod=" << rawData->rodId() << " ssw=" << rawData->sswId()
163 << " slb=" << rawData->slbId() << " bitpos=" << rawData->bitpos() << " orFlag=" << orFlag);
164 }
165 continue;
166 }
167
168 // convert RawData to Digit
169 std::unique_ptr<TgcDigit> newDigit(m_tgcRdoDecoderTool->getDigit(rawData, orFlag));
170
171 // check if converted correctly
172 if (!newDigit) continue;
173
174 // check new element or not
175 IdentifierHash coll_hash;
176 if (m_idHelperSvc->tgcIdHelper().get_hash(elementId, coll_hash, &tgcContext)) {
177 ATH_MSG_WARNING("Unable to get TGC digit collection hash "
178 << "context begin_index = " << tgcContext.begin_index()
179 << " context end_index = " << tgcContext.end_index() << " the identifier is ");
180 elementId.show();
181 }
182
183 if (elementId != oldElementId) {
184 // get collection
185 const auto *coll = tgcContainer->indexFindPtr(coll_hash);
186 if (nullptr != coll) {
187 TgcDigitCollection* aCollection ATLAS_THREAD_SAFE = const_cast<TgcDigitCollection*>(coll); // FIXME
188 collection = aCollection;
189 } else {
190 // create new collection
191 ATH_MSG_DEBUG("Created a new digit collection : " << coll_hash);
192 collection = new TgcDigitCollection(elementId, coll_hash);
193 ATH_CHECK(tgcContainer->addCollection(collection, coll_hash));
194 }
195
196 oldElementId = elementId;
197 }
198
199 if (!collection) {
200 ATH_MSG_WARNING("TgcRdoToTgcDigit::decodeTgc TgcDigitCollection* collection is null.");
201 return StatusCode::SUCCESS;
202 }
203
204 // check duplicate digits
205 bool duplicate = false;
206 for (const TgcDigit* digit : *collection) {
207 if ((newDigit->identify() == digit->identify()) && (newDigit->bcTag() == digit->bcTag())) {
208 duplicate = true;
209 ATH_MSG_DEBUG("Duplicate TGC Digit removed");
210 break;
211 }
212 }
213 if (!duplicate) {
214 // add the digit to the collection
215 collection->push_back(newDigit.release());
216 }
217 }
218 }
219 return StatusCode::SUCCESS;
220}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define ATLAS_THREAD_SAFE
bool msgLvl(const MSG::Level lvl) const
size_type size() const noexcept
Returns the number of elements in the collection.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
size_type begin_index() const
Definition IdContext.h:45
size_type end_index() const
Definition IdContext.h:46
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
virtual StatusCode addCollection(const T *coll, IdentifierHash hashId) override final
insert collection into container with id hash if IDC should not take ownership of collection,...
This is a "hash" representation of an Identifier.
void show() const
Print out in hex form.
bool isPresent() const
Is the referenced object present in SG?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
Use IdentifiableContainer with TgcDigitCollection.
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
ServiceHandle< MuonTGC_CablingSvc > m_tgcCabling
Gaudi::Property< bool > m_show_warning_level_invalid_TGC_A09_SSW6_hit
virtual StatusCode execute(const EventContext &ctx) const override final
StatusCode decodeTgc(const TgcRdo *, TgcDigitContainer *, Identifier &) const
virtual StatusCode initialize() override final