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