ATLAS Offline Software
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());
10  ATH_CHECK(m_tgcRdoDecoderTool.retrieve());
13  ATH_CHECK(m_tgcCabling.retrieve());
14  return StatusCode::SUCCESS;
15 }
16 
17 StatusCode 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 
39 StatusCode 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 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TgcRawData::SLB_TYPE_DOUBLET_STRIP
@ SLB_TYPE_DOUBLET_STRIP
Definition: TgcRawData.h:33
IdentifiableContainerMT::addCollection
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,...
Definition: IdentifiableContainerMT.h:297
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
TgcDigit::bcTag
uint16_t bcTag() const
Definition: TgcDigit.cxx:31
IdContext::end_index
size_type end_index() const
Definition: IdContext.h:46
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
TgcRdoToTgcDigit::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: TgcRdoToTgcDigit.h:29
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
TgcRdoToTgcDigit::m_tgcDigitKey
SG::WriteHandleKey< TgcDigitContainer > m_tgcDigitKey
Definition: TgcRdoToTgcDigit.h:35
IdContext::begin_index
size_type begin_index() const
Definition: IdContext.h:45
TgcRdoToTgcDigit::m_tgcRdoDecoderTool
ToolHandle< Muon::ITGC_RDO_Decoder > m_tgcRdoDecoderTool
Definition: TgcRdoToTgcDigit.h:28
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TgcDigitCollection
Definition: TgcDigitCollection.h:17
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
IdentifiableContainerMT::const_iterator
Definition: IdentifiableContainerMT.h:79
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
Identifier::show
void show() const
Print out in hex form.
Definition: Identifier.cxx:30
TgcDigit
Definition: TgcDigit.h:21
TgcRdoToTgcDigit::initialize
virtual StatusCode initialize() override final
Definition: TgcRdoToTgcDigit.cxx:8
TgcRdoToTgcDigit::m_tgcCabling
ServiceHandle< MuonTGC_CablingSvc > m_tgcCabling
Definition: TgcRdoToTgcDigit.h:32
TgcRdoToTgcDigit::execute
virtual StatusCode execute(const EventContext &ctx) const override final
Definition: TgcRdoToTgcDigit.cxx:17
IdentifiableContainerMT::indexFindPtr
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,...
Definition: IdentifiableContainerMT.h:289
MuonDigit::identify
Identifier identify() const
Definition: MuonDigit.h:30
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TgcRawData
An unit object of TGC ROD output.
Definition: TgcRawData.h:23
DEBUG
#define DEBUG
Definition: page_access.h:11
TgcRdoToTgcDigit::decodeTgc
StatusCode decodeTgc(const TgcRdo *, TgcDigitContainer *, Identifier &) const
Definition: TgcRdoToTgcDigit.cxx:39
TgcRdo
Definition: TgcRdo.h:22
TgcDigitContainer
Use IdentifiableContainer with TgcDigitCollection.
Definition: TgcDigitContainer.h:53
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
value_type
Definition: EDM_MasterSearch.h:11
TgcRdoToTgcDigit::m_show_warning_level_invalid_TGC_A09_SSW6_hit
Gaudi::Property< bool > m_show_warning_level_invalid_TGC_A09_SSW6_hit
Definition: TgcRdoToTgcDigit.h:30
IdContext
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition: IdContext.h:26
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TgcRdoToTgcDigit::m_tgcRdoKey
SG::ReadHandleKey< TgcRdoContainer > m_tgcRdoKey
Definition: TgcRdoToTgcDigit.h:34
TgcRdoToTgcDigit.h
Identifier
Definition: IdentifierFieldParser.cxx:14