ATLAS Offline Software
RpcRdoToPrepDataToolMT.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 
7 #include "GaudiKernel/ThreadLocalContext.h"
13 #include "TrkSurfaces/Surface.h"
16 #include "GeoModelKernel/throwExcept.h"
17 using namespace MuonGM;
18 using namespace Trk;
19 namespace Muon{
22  m_idHelperSvc{idHelperSvc} {
23  const IdentifierHash hashMax = m_idHelperSvc->rpcIdHelper().module_hash_max();
24  rpcPrepDataCollections.resize(hashMax);
25  rpcCoinDataCollections.resize(hashMax);
26 }
28 
29  const IdentifierHash rpdModHash = m_idHelperSvc->moduleHash(chanId);
30  std::unique_ptr<RpcPrepDataCollection>& coll = rpcPrepDataCollections[rpdModHash];
31  if (!coll) {
32  coll = std::make_unique<RpcPrepDataCollection>(rpdModHash);
33  coll->setIdentifier(m_idHelperSvc->chamberId(chanId));
34  }
35  return coll.get();
36 }
38  const IdentifierHash rpdModHash = m_idHelperSvc->moduleHash(chanId);
39  std::unique_ptr<RpcCoinDataCollection>& coll = rpcCoinDataCollections[rpdModHash];
40  if (!coll) {
41  coll = std::make_unique<RpcCoinDataCollection>(rpdModHash);
42  coll->setIdentifier(m_idHelperSvc->chamberId(chanId));
43  }
44  return coll.get();
45 }
46 
47 
48 //___________________________________________________________________________
50  // perform necessary one-off initialization
51 
52  ATH_MSG_INFO("properties are ");
53  ATH_MSG_INFO("produceRpcCoinDatafromTriggerWords " <<m_producePRDfromTriggerWords);
54  ATH_MSG_INFO("reduceCablingOverlap " << m_reduceCablingOverlap);
55  ATH_MSG_INFO("solvePhiAmbiguities " << m_solvePhiAmbiguities);
56  ATH_MSG_INFO("timeShift " << m_timeShift);
58  ATH_MSG_WARNING("Inconsistent setting of properties (solvePhiAmbiguities entails reduceCablingOverlap)");
59  ATH_MSG_WARNING("Resetting reduceCablingOverlap to true");
61  }
62  ATH_MSG_INFO("etaphi_coincidenceTime " << m_etaphi_coincidenceTime);
63  ATH_MSG_INFO("overlap_timeTolerance " << m_overlap_timeTolerance);
64  ATH_MSG_INFO("Correct prd time from cool db " << m_RPCInfoFromDb);
65  ATH_CHECK(m_rpcRdoDecoderTool.retrieve());
66  ATH_CHECK(m_idHelperSvc.retrieve());
71  ATH_CHECK(m_nRpcCablingKey.initialize(!m_rdoNrpcContainerKey.empty()));
72  // If we don't configure the NRPC RDO
73  // key, the cabling is needed either.
79  ATH_CHECK(m_xAODKey.initialize(!m_xAODKey.empty()));
81  return StatusCode::SUCCESS;
82 }
84  ATH_MSG_INFO(" Total number of spurious RPC channels in RAW data that are not associated to RPC strips: " << m_spuriousHitCounter);
85  return StatusCode::SUCCESS;
86 }
87 StatusCode RpcRdoToPrepDataToolMT::loadProcessedChambers(const EventContext& ctx, State& state) const {
88  const int modHashMax = m_idHelperSvc->rpcIdHelper().module_hash_max();
89  if (!m_prdContainerCacheKey.key().empty()) {
91  if (!update.isValid()) {
92  ATH_MSG_FATAL("Invalid UpdateHandle " << m_prdContainerCacheKey.key());
93  return StatusCode::FAILURE;
94  }
95  state.prepDataCont = std::make_unique<RpcPrepDataContainer>(update.ptr());
96  for (const RpcPrepDataCollection* coll : *state.prepDataCont) {
97  state.m_decodedOfflineHashIds.insert(coll->identifyHash());
98  }
99  } else{
100  state.prepDataCont = std::make_unique<RpcPrepDataContainer>(modHashMax);
101  }
102  if (m_coindataContainerCacheKey.key().empty()) {
103  // without the cache we just record the container
104  state.coinDataCont = std::make_unique<RpcCoinDataContainer>(modHashMax);
105  } else {
106  // use the cache to get the container
108  if (!update.isValid()) {
109  ATH_MSG_FATAL("Invalid UpdateHandle "<< m_coindataContainerCacheKey.key());
110  return StatusCode::FAILURE;
111  }
112  state.coinDataCont = std::make_unique<RpcCoinDataContainer>(update.ptr());
113  for (const RpcCoinDataCollection* coll : *state.coinDataCont) {
114  state.m_decodedOfflineHashIds.insert(coll->identifyHash());
115  }
116  }
117  return StatusCode::SUCCESS;
118 }
122  const std::vector<IdentifierHash>& idVect) const {
123  ATH_MSG_DEBUG("Calling Core decode function from MT decode function (hash vector)");
124  State state{m_idHelperSvc.get()};
125  ATH_CHECK(loadProcessedChambers(ctx, state));
126 
127  ATH_CHECK(decodeImpl(ctx, state, idVect, true));
128  ATH_CHECK(processNrpcRdo(ctx, state));
129  ATH_MSG_DEBUG("Core decode processed in MT decode (hash vector)");
130 
133 
134  return StatusCode::SUCCESS;
135 }
136 
140  const std::vector<uint32_t>& robIds) const {
141  ATH_MSG_DEBUG("Calling Core decode function from MT decode function (ROB vector)");
142  State state{m_idHelperSvc.get()};
143  ATH_CHECK(loadProcessedChambers(ctx, state));
144 
145  ATH_CHECK(decodeImpl(ctx, state, robIds, true));
146  ATH_CHECK(processNrpcRdo(ctx, state));
147  ATH_MSG_DEBUG("Core decode processed in MT decode (ROB vector)");
148 
151 
152  return StatusCode::SUCCESS;
153 }
155  State state{m_idHelperSvc.get()};
156  ATH_CHECK(loadProcessedChambers(ctx, state));
159  return StatusCode::SUCCESS;
160 }
161 
163 
165  if (!m_xAODKey.empty()) {
166  writeHandleXAOD = SG::WriteHandle{m_xAODKey, ctx};
167  ATH_CHECK(writeHandleXAOD.record(std::make_unique<xAOD::RpcStripContainer>(),
168  std::make_unique<xAOD::RpcStripAuxContainer>()));
169  }
170  const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
171  for (std::unique_ptr<RpcPrepDataCollection>& collection : state.rpcPrepDataCollections) {
172  if (!collection || collection->empty()) {
173  continue;
174  }
175  if (!m_xAODKey.empty()) {
178  std::vector<const RpcPrepData*> sortMe{collection->begin(), collection->end()};
179  std::ranges::sort(sortMe, IdentifierByDetElSorter{m_idHelperSvc.get()});
180  for (const RpcPrepData* prd : sortMe) {
181  const Identifier id = prd->identify();
182  xAOD::RpcStrip* strip = writeHandleXAOD->push_back(std::make_unique<xAOD::RpcStrip>());
183  strip->setDoubletPhi(idHelper.doubletPhi(id));
184  strip->setGasGap(idHelper.gasGap(id));
185  strip->setMeasuresPhi(idHelper.measuresPhi(id));
186  strip->setStripNumber(idHelper.channel(id));
187  strip->setAmbiguityFlag(prd->ambiguityFlag());
188  strip->setTimeOverThreshold(prd->timeOverThreshold());
189  strip->setTime(prd->time());
190  strip->setTimeCovariance(std::pow(m_stripTimeResolution, 2));
191  strip->setTriggerInfo(prd->triggerInfo());
192  xAOD::MeasVector<1> locPos{prd->localPosition().x()};
193  xAOD::MeasMatrix<1> locCov{prd->localCovariance()(0,0)};
194  strip->setMeasurement(m_idHelperSvc->detElementHash(id), std::move(locPos), std::move(locCov));
195  }
196  }
197 
198  const IdentifierHash hash = collection->identifyHash();
199  // If not present, get a write lock for the hash and move collection
201  if (lock.alreadyPresent()) {
202  ATH_MSG_DEBUG("RpcPrepDataCollection already contained in IDC "
203  << m_idHelperSvc->toString(collection->identify()));
204  continue;
205  }
206  ATH_CHECK(lock.addOrDelete(std::move(collection)));
207  ATH_MSG_DEBUG("PRD hash " << hash << " has been moved to cache container");
208  }
209  state.rpcPrepDataCollections.clear();
210 
211  if (msgLvl(MSG::DEBUG)) {
212  for (const auto& [hash, ptr] : state.prepDataCont->GetAllHashPtrPair()) {
213  ATH_MSG_DEBUG("Contents of CONTAINER in this view : " << hash);
214  }
215  }
216  SG::WriteHandle rpcPRDHandle{m_rpcPrepDataContainerKey, ctx};
217  ATH_CHECK(rpcPRDHandle.record(std::move(state.prepDataCont)));
218  ATH_MSG_DEBUG("Created container " << m_rpcPrepDataContainerKey.key());
219 
220  return StatusCode::SUCCESS;
221 }
222 
225  return StatusCode::SUCCESS;
226  }
227 
228  // Take localContainer and transfer contents to rpcCoinHandle
229  for (std::unique_ptr<RpcCoinDataCollection>& collection : state.rpcCoinDataCollections) {
230  if (!collection || collection->empty()) {
231  continue;
232  }
233  const IdentifierHash hash = collection->identifyHash();
234  // If not present, get a write lock for the hash and move collection
236  if (lock.alreadyPresent()) {
237  ATH_MSG_DEBUG("RpcCoinDataCollection already contained in IDC "
238  << m_idHelperSvc->toString(collection->identify()));
239  continue;
240  }
241  ATH_CHECK(lock.addOrDelete(std::move(collection)));
242  ATH_MSG_DEBUG("Coin hash " << hash << " has been moved to cache container");
243  }
244  state.rpcCoinDataCollections.clear();
245  if (msgLvl(MSG::DEBUG)) {
246  for (const auto& [hash, ptr] : state.coinDataCont->GetAllHashPtrPair()) {
247  ATH_MSG_DEBUG("Contents of LOCAL in this view : " << hash);
248  }
249  }
252  ATH_CHECK(rpcCoinHandle.record(std::move(state.coinDataCont)));
253 
254  ATH_MSG_DEBUG("Created container " << m_rpcCoinDataContainerKey.key());
255  // For additional information on the contents of the cache-based container,
256  // this function can be used printMTCoinData (*rpcCoinHandle);
257 
258  return StatusCode::SUCCESS;
259 }
260 
261 //___________________________________________________________________________
262 StatusCode RpcRdoToPrepDataToolMT::decodeImpl(const EventContext& ctx, State& state,
263  const std::vector<IdentifierHash>& idVect,
264  bool firstTimeInTheEvent) const {
265  int sizeVectorRequested = idVect.size();
266  ATH_MSG_DEBUG("Decode method called for " << sizeVectorRequested << " offline collections");
267  if (sizeVectorRequested == 0){
268  ATH_MSG_DEBUG("Decoding the entire event");
269  }
270  // create an empty vector of hash ids to be decoded (will be filled if
271  // RoI-based and left empty if full-scan)
272  std::vector<IdentifierHash> idVectToBeDecoded;
273  idVectToBeDecoded.reserve(idVect.size());
274 
275  if (firstTimeInTheEvent) {
276  state.m_fullEventDone = sizeVectorRequested == 0;
277  } else {
278  if (state.m_fullEventDone) {
279  ATH_MSG_DEBUG("Whole event has already been decoded; nothing to do.");
280  return StatusCode::SUCCESS;
281  }
282  if (sizeVectorRequested == 0) {
283  state.m_fullEventDone = true;
284  }
285  }
286 
287  if (sizeVectorRequested != 0) {
288  // the program goes in here only if RoI-based decoding has been called and
289  // the full event is not already decoded this code ensures decoding of every
290  // offline hash id is called only once
291  for (const IdentifierHash& itHashId : idVect) {
292  if (state.m_decodedOfflineHashIds.insert(itHashId).second)
293  idVectToBeDecoded.push_back(itHashId);
294  }
295 
296  if (idVectToBeDecoded.empty()) {
297  ATH_MSG_DEBUG("All requested offline collections have already been decoded; nothing to do.");
298  return StatusCode::SUCCESS;
299  } else {
300  ATH_MSG_DEBUG(idVectToBeDecoded.size()
301  << " offline collections have not yet been decoded and will be decoded now.");
302  ATH_MSG_VERBOSE("The list of offline collection hash ids to be decoded:"<<std::endl<<idVectToBeDecoded);
303  }
304  }
305 
306  // if RPC decoding is switched off stop here
307  if (!m_decodeData) {
308  ATH_MSG_DEBUG("Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
309  return StatusCode::SUCCESS;
310  }
311 
312  ATH_MSG_DEBUG("Decoding RPC RDO into RPC PrepRawData");
313 
314  SG::ReadCondHandle rpcCabling{m_rpcReadKey, ctx};
315  // if the vector requested has size 0, we need to perform a scan of the entire
316  // RDO container otherwise select the pads to be decoded
317  std::vector<IdentifierHash> rdoHashVec;
318  if (sizeVectorRequested != 0) {
319  ATH_MSG_DEBUG("Looking for pads IdHash to be decoded for the requested collection Ids");
320  ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
321  }
322 
324  IdContext rpcContext = m_idHelperSvc->rpcIdHelper().module_context();
325 
326  // we come here if the rdo container is already in SG (for example in MC RDO!)
327  ATH_MSG_DEBUG("Retrieving Rpc PAD container from the store");
328  auto rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
329  if (!rdoContainerHandle.isValid()) {
330  ATH_MSG_ERROR("Retrieval of RPC RDO container failed ! "<<m_rdoContainerKey.fullKey());
331  return StatusCode::FAILURE;
332  }
333 
336  if (rdoContainerHandle->numberOfCollections() == 0) {
337  // empty pad container - no rpc rdo in this event
338  ATH_MSG_DEBUG("Empty pad container - no rpc rdo in this event ");
339  return StatusCode::SUCCESS;
340  }
341  ATH_MSG_DEBUG("Not empty pad container in this event ");
342 
343  // start here to process the RDO (for the full event of for a fraction of it)
344  bool processingetaview{m_solvePhiAmbiguities}, processingphiview{false};
345  bool doingSecondLoopAmbigColls = false;
346  while (processingetaview || processingphiview || (!m_solvePhiAmbiguities)) {
347  int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
348  if (processingphiview) {
349  state.m_ambiguousCollections.clear();
350  }
351  ATH_MSG_DEBUG("*** Processing "<<(processingetaview ? "eta" : "phi")<<" view ");
352  // seeded decoding
353  if (sizeVectorRequested != 0) {
354  ATH_MSG_DEBUG("Start loop over pads hashes - seeded mode ");
355  for (const IdentifierHash& iPadHash : rdoHashVec) {
356  const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(iPadHash);
357  if (!rdoColl) {
358  ATH_MSG_DEBUG("Requested pad with online id "<< iPadHash << " not found in the rdoContainerHandle.");
359  continue;
360  }
361  ++ipad;
362 
363  ATH_MSG_DEBUG("A new pad here n. " << ipad << ", online id "<< rdoColl->identifyHash()
364  << ", with " << rdoColl->size() << " CM inside ");
365  ATH_CHECK(processPad(ctx, state, rdoColl, processingetaview,
366  processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
367 
368  } // end loop over requested pads hashes
369  } else { // unseeded // whole event
370  ATH_MSG_DEBUG("Start loop over pads - unseeded mode ");
371  for (const RpcPad* rdoColl : *rdoContainerHandle) {
372  // loop over all elements of the pad container
373  if (rdoColl->empty()){
374  continue;
375  }
376  ++ipad;
377  ATH_MSG_DEBUG("A new pad here n. " << ipad << ", online id "<< rdoColl->identifyHash()
378  << ", with " << rdoColl->size() << " CM inside ");
379 
380  ATH_CHECK(processPad(ctx, state, rdoColl, processingetaview,
381  processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
382  } // end loop over pads
383  }
384 
385  if (processingetaview) {
386  processingetaview = false;
387  processingphiview = true;
388  nEtaPrepRawData = nPrepRawData;
389  ATH_MSG_DEBUG("*** " << nEtaPrepRawData << " eta PrepRawData registered");
390  } else {
391  processingphiview = false;
392  nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
393  ATH_MSG_DEBUG("*** " << nPhiPrepRawData << " phi PrepRawData registered");
394  if (!state.m_ambiguousCollections.empty()) {
395  // loop again for unrequested collections stored with ambiguous phi hits
396  doingSecondLoopAmbigColls = true;
397  processingetaview = true;
398  ATH_MSG_DEBUG(state.m_ambiguousCollections.size() << " ambiguous collections were stored:");
399  idVectToBeDecoded.clear();
400  rdoHashVec.clear();
401  for (const IdentifierHash& itAmbiColl : state.m_ambiguousCollections) {
402  ATH_MSG_DEBUG(itAmbiColl << " ");
403  idVectToBeDecoded.push_back(itAmbiColl);
404  state.m_decodedOfflineHashIds.insert(itAmbiColl);
405  }
406  ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
407  }
408  }
409  if (!m_solvePhiAmbiguities) {
410  ATH_MSG_DEBUG("*** " << nPrepRawData << " PrepRawData registered");
411  break;
412  }
413  }
414 
415  ATH_MSG_DEBUG("*** Final Cleanup ");
416  return StatusCode::SUCCESS;
417 }
418 
419 //___________________________________________________________________________
420 StatusCode RpcRdoToPrepDataToolMT::decodeImpl(const EventContext& ctx, State& state,
421  const std::vector<uint32_t>& robIds, bool firstTimeInTheEvent) const {
422  // ROB-based decoding is only applied in seeded mode. Full scan should use the
423  // hashId-based method with empty requested collections vector.
424 
425  int sizeVectorRequested = robIds.size();
426  ATH_MSG_DEBUG("Decode method called for " << sizeVectorRequested << " ROBs");
427 
428  std::vector<uint32_t> robIdsToBeDecoded{};
429  robIdsToBeDecoded.reserve(robIds.size());
430 
431  if (firstTimeInTheEvent) {
432  state.m_fullEventDone = false;
433  } else {
434  if (state.m_fullEventDone) {
435  ATH_MSG_DEBUG("Whole event has already been decoded; nothing to do.");
436  return StatusCode::SUCCESS;
437  }
438  }
439 
440  // check which of the requested robs are not yet decoded
441  for (uint32_t robid : robIds) {
442  if (state.m_decodedRobIds.insert(robid).second) {
443  robIdsToBeDecoded.push_back(robid);
444  }
445  }
446 
447  if (robIdsToBeDecoded.empty()) {
448  ATH_MSG_DEBUG("All requested ROBs have already been decoded; nothing to do.");
449  return StatusCode::SUCCESS;
450  }
451  ATH_MSG_DEBUG(robIdsToBeDecoded.size()<< " ROBs have not yet been decoded and will be decoded now.");
452  if (msgLvl(MSG::VERBOSE)) {
453  ATH_MSG_VERBOSE("The list of ROB Ids to be decoded:");
454  for (uint32_t robid : robIdsToBeDecoded)
455  ATH_MSG_VERBOSE("0x" << MSG::hex << robid << MSG::dec << " ");
456  }
457 
458  SG::ReadCondHandle rpcCabling{m_rpcReadKey, ctx};
459 
460  // if all robs will be decoded after the current execution of the method, set
461  // the flag m_fullEventDone
462  if (state.m_decodedRobIds.size() == rpcCabling->giveFullListOfRobIds().size())
463  state.m_fullEventDone = true;
464 
465  // if RPC decoding is switched off stop here
466  if (!m_decodeData) {
467  ATH_MSG_DEBUG("Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
468  return StatusCode::SUCCESS;
469  }
470 
471  ATH_MSG_DEBUG("Decoding RPC RDO into RPC PrepRawData");
472 
473  // we come here if the rdo container is already in SG (for example in MC RDO!)
474  ATH_MSG_DEBUG("Retrieving Rpc PAD container from the store");
475  auto rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
476  if (!rdoContainerHandle.isValid()) {
477  ATH_MSG_WARNING("Retrieval of RPC RDO container failed ! "<<m_rdoContainerKey.fullKey());
478  return StatusCode::SUCCESS;
479  }
480 
481  // here the RDO container is retrieved and filled -whatever input type we
482  // start with- => check the size
483  if (rdoContainerHandle->empty()) {
484  // empty pad container - no rpc rdo in this event
485  ATH_MSG_DEBUG("Empty pad container - no rpc rdo in this event ");
486  return StatusCode::SUCCESS;
487  }
488  ATH_MSG_DEBUG("Not empty pad container in this event ");
489 
490  // obtain a list of PADs (RDOs) to be processed
491  std::vector<IdentifierHash> rdoHashVec;
492  rdoHashVec.reserve(13 * robIdsToBeDecoded.size()); // most ROBs have 13 RDOs, some have less
493  ATH_CHECK(rpcCabling->giveRDO_fromROB(robIdsToBeDecoded, rdoHashVec));
494 
495  // start here to process the RDOs
496  bool processingetaview = true;
497  bool processingphiview = false;
498  if (!m_solvePhiAmbiguities){
499  processingetaview = false;
500  }
501  while (processingetaview || processingphiview || (!m_solvePhiAmbiguities)) {
502  int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
503  if (processingphiview){
504  state.m_ambiguousCollections.clear();
505  }
506  ATH_MSG_DEBUG("*** Processing "<<(processingetaview? "eta" : "phi")<<" view ");
507 
508  // seeded decoding (for full scan, use the hashId-based method)
509  ATH_MSG_DEBUG("Start loop over pads hashes - seeded mode ");
510 
511  for (const IdentifierHash& padHashId : rdoHashVec) {
512  const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(padHashId);
513  if (!rdoColl) {
514  ATH_MSG_DEBUG("Requested pad with online id "<< padHashId << " not found in the rdoContainerHandle.");
515  continue;
516  }
517  ++ipad;
518  ATH_MSG_DEBUG("A new pad here n."<< ipad << ", online id " << rdoColl->identifyHash()
519  << ", with " << rdoColl->size() << " CM inside ");
520  ATH_CHECK(processPad(ctx, state, rdoColl, processingetaview,
521  processingphiview, nPrepRawData, rdoHashVec, false));
522  }
523 
524  if (processingetaview) {
525  processingetaview = false;
526  processingphiview = true;
527  nEtaPrepRawData = nPrepRawData;
528  ATH_MSG_DEBUG("*** " << nEtaPrepRawData << " eta PrepRawData registered");
529  } else {
530  processingphiview = false;
531  nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
532  ATH_MSG_DEBUG("*** " << nPhiPrepRawData << " phi PrepRawData registered");
533  }
534  if (!m_solvePhiAmbiguities) {
535  ATH_MSG_DEBUG("*** " << nPrepRawData << " PrepRawData registered");
536  break;
537  }
538  }
539 
540  ATH_MSG_DEBUG("*** Final Cleanup ");
541 
542  return StatusCode::SUCCESS;
543 
544 }
545 
546 StatusCode RpcRdoToPrepDataToolMT::processPad(const EventContext& ctx, State& state, const RpcPad* rdoColl,
547  bool& processingetaview, bool& processingphiview, int& nPrepRawData,
548  const std::vector<IdentifierHash>& idVect,
549  bool doingSecondLoopAmbigColls) const {
550 
551  const RpcIdHelper& idHelper = m_idHelperSvc->rpcIdHelper();
552 
553  std::unordered_set<IdentifierHash>& ambiguousCollections{state.m_ambiguousCollections};
554  ATH_MSG_DEBUG("***************** Start of processPad eta/phiview "<< processingetaview << "/" << processingphiview);
555  //{processPad
556  // Get pad online id and sector id
557  uint16_t padId = rdoColl->onlineId();
558  uint16_t sectorId = rdoColl->sector();
559  ATH_MSG_DEBUG("***************** for Pad online Id "<< padId << " m_logic sector ID " << sectorId);
560 
561  // Create an RPC PrepDataCollection
562  Identifier oldId{}, oldIdTrg{};
563  ATH_MSG_VERBOSE("Init pointer to RpcPrepDataCollection ");
564  RpcPrepDataCollection* collection{nullptr};
565  RpcCoinDataCollection* collectionTrg{nullptr};
566  IdentifierHash rpcHashId{0};
567 
568  SG::ReadCondHandle rpcCabling{m_rpcReadKey, ctx};
569 
570  // For each pad, loop on the coincidence matrices
571  int icm = 0;
572  for (const RpcCoinMatrix* coinMat : *rdoColl) {
573  ++icm;
574  bool etaview = !m_isMC;
575  bool highPtCm = false;
576  // Get CM online Id
577  uint16_t cmaId = coinMat->onlineId();
578  ATH_MSG_DEBUG("A new CM here n. "<< icm << " CM online ID " << cmaId<< " with n. of hits = " << coinMat->size()
579  <<", empty: "<<coinMat->empty());
580  ATH_MSG_DEBUG((cmaId < 4? "low": "high") <<" pt ");
581  if (cmaId < 2) {
582  etaview = m_isMC;
583  } else if (cmaId >=4) {
584  highPtCm = true;
585  if (cmaId < 6) {
586  etaview = m_isMC;
587  }
588  }
589  ATH_MSG_DEBUG(" eta view = " << etaview<<", processingetaview: "<<processingetaview
590  <<", processingphiview: "<<processingphiview);
591 
592  if (processingetaview && !etaview){
593  continue;
594  } else if (processingphiview && etaview) {
595  continue;
596  }
597  if (coinMat->empty()) {
598  ATH_MSG_DEBUG("Empty CM");
599  }
600  // For each CM, loop on the fired channels
601  int idata = 0;
602  for (RpcCoinMatrix::const_iterator itD = coinMat->begin(); itD != coinMat->end(); ++itD) {
603  const RpcFiredChannel* rpcChan{*itD};
604  idata++;
605  // trigger related quantities
606  unsigned short threshold = 99;
607  unsigned short overlap = 99;
608 
609  // flags defining the processing mode of this hit
610  bool solvePhiAmb_thisHit = m_solvePhiAmbiguities;
611  bool reduceCablOvl_thisHit = m_reduceCablingOverlap;
612 
613  ATH_MSG_DEBUG("A new CM Hit " << idata);
614  ATH_MSG_DEBUG("RpcFiredChannel: bcid " << rpcChan->bcid() << " time " << rpcChan->time()
615  << " ijk "<< rpcChan->ijk() <<" ch " << ( rpcChan->ijk() < 7 ? rpcChan->channel() : -1));
616  // check if trigger hit
617  // select the cases: ijk = 0 and high p, ijk= 6, ijk=7
618  bool triggerHit = false;
619  bool toSkip = false;
620  processTriggerHitHypothesis(itD, coinMat->end(), highPtCm, triggerHit, threshold, overlap, toSkip);
621  if (toSkip) {
622  continue;
623  }
624  if (triggerHit) {
625  // here ijk = 6 or ijk = 0 in high pt cm
626  // keep all pivot + trigger info (even if duplicated [should never
627  // happen, for pivot hits])
628  solvePhiAmb_thisHit = false;
629  reduceCablOvl_thisHit = false;
630  ATH_MSG_DEBUG("RpcFiredChannel: it's a triggerHit or a lowPt coinc. in a high pt CM \n"
631  << " ijk = " << rpcChan->ijk() << " isHighPtCM " << highPtCm
632  << " thr/ovl = " << threshold << "/" << overlap);
633  }
634 
635  // here decode (get offline ids for the online indices of this hit)
636  double time = 0.;
637  std::vector<Identifier> digitVec{m_rpcRdoDecoderTool->getOfflineData(rpcChan, sectorId, padId,
638  cmaId, time, rpcCabling.cptr())};
639  time += m_timeShift;
640 
641  int nMatchingEtaHits{0}, nDuplicatePhiHits{0};
642  bool unsolvedAmbiguity{false}, notFinished{true};
643  // allow for 2 iterations in case there are phi digits without matching
644  // eta (eta inefficiency) all eta digits, not already recorded, will be
645  // registered as PrepRawData and all phi digits, not yet recorded and with
646  // a eta digit in the same module and gap, will produce a PrepRawData. Phi
647  // digits without a eta match will not be recorded at the first iteration.
648  // If all phi digits do not have a eta match, they will be all recorded as
649  // PrepRawData in the second iteration (the ambiguity will remain
650  // unsolved)
651  while (notFinished) {
652  // Loop on the digits corresponding to the fired channel
653  ATH_MSG_DEBUG("size of the corresponding list of ID = " << digitVec.size());
654  if (digitVec.empty()) {
655  ATH_MSG_DEBUG("going to next CM hit");
656  notFinished = false;
657  continue;
658  }
659  for (const Identifier& channelId : digitVec) {
660  // Prepare the prepdata for this identifier
661  // channel Id
662  rpcHashId = m_idHelperSvc->moduleHash(channelId);
663  const Identifier parentId = idHelper.parentID(channelId);
664 
665  // There is some ambiguity in the channel/sectorId's, so need to
666  // explicitly filter out hashIDs outside of the RoI in seeded decoding
667  // mode
668  if (!idVect.empty() && std::find(idVect.begin(), idVect.end(), rpcHashId) == idVect.end()) {
669  continue;
670  }
671  ATH_MSG_DEBUG("CM Hit decoded into offline Id "<< m_idHelperSvc->toString(channelId) << " time "<< time);
672  ATH_MSG_DEBUG(" oldID = " << m_idHelperSvc->toString(oldId) <<" oldIDtrg = " << m_idHelperSvc->toString(oldIdTrg));
673  bool hasAMatchingEtaHit = 0;
674  // current collection has Id "parentId"; get it from the container !
675  if (triggerHit) {
676  if ((oldIdTrg != parentId) || !collectionTrg) {
677  // Get collection from IDC if it exists, or create it and add it
678  // if not.
679  ATH_MSG_DEBUG(" Looking/Creating a collection with ID = "<< m_idHelperSvc->toString(parentId)
680  << " hash = " << rpcHashId);
681  collectionTrg = state.getCoinCollection(parentId);
682  oldIdTrg = parentId;
683  ATH_MSG_DEBUG(" Resetting oldIDtrg to current parentID = "<< m_idHelperSvc->toString(oldIdTrg));
684  }
685  } else if ((oldId != parentId) || !collection) {
686  // Get collection from IDC if it exists, or create it and add it if
687  // not.
688  ATH_MSG_DEBUG(" Looking/Creating a collection with ID = "<< m_idHelperSvc->toString(parentId) << " hash = "<< rpcHashId);
689  collection = state.getPrepCollection(parentId);
690  oldId = parentId;
691  ATH_MSG_DEBUG(" Resetting oldID to current parentID = "<< m_idHelperSvc->toString(oldId));
692  }
693 
694  // check if the data has already been recorded
695  // (if you want to reduce the redundancy due to cabling overlap and if
696  // the collection is not empty)
697  bool duplicate = false;
698  if (reduceCablOvl_thisHit) {
699  ATH_MSG_VERBOSE("Check for duplicates in coll. with size "<< collection->size());
700  for (RpcPrepData* rpc : *collection) {
701  const Identifier existId{rpc->identify()};
702  if (channelId == existId &&
703  std::abs(time - rpc->time()) < m_overlap_timeTolerance) {
704  duplicate = true;
705  hasAMatchingEtaHit = false; // we don't want to increment the
706  // number of strips with
707  // a matching eta due to a cabling overlap
708  ATH_MSG_VERBOSE("Duplicated RpcPrepData(not recorded) = " << m_idHelperSvc->toString(channelId));
709  float previous_time = rpc->time();
710  // choose the smallest time within timeTolerance
711  if (time < previous_time) {
712  rpc->m_time = time;
713  ATH_MSG_DEBUG("time of the prd previously stored is now updated with "
714  << "current hit time: "<< previous_time << " -> " << rpc->time());
715  }
716  break; // this break is why we cannot have
717  // solvePhiAmb_thisHit = true and
718  // reduceCablOvl_thisHit= false
719  }
720 
721 
722  if (processingphiview && solvePhiAmb_thisHit && !unsolvedAmbiguity && !idHelper.measuresPhi(existId) &&
723  m_idHelperSvc->gasGapId(existId) == m_idHelperSvc->gasGapId(channelId) &&
724  std::abs(time - rpc->time()) < m_etaphi_coincidenceTime) {
725  hasAMatchingEtaHit = true;
726  ATH_MSG_VERBOSE("There's a matching eta hit with id "<< m_idHelperSvc->toString(existId));
727  // here there can be a break ? NO, we need to
728  // keep looping in order to check
729  // if this preprawdata has been already
730  // recorded (due to cabling overlaps)
731  }
732  }
733  if (hasAMatchingEtaHit)
734  nMatchingEtaHits++; // Number of phi strips (possibly
735  // corresponding to this CM hit)
736  // with a matching eta
737  if (processingphiview && duplicate)
738  nDuplicatePhiHits++; // Number of phi strips (possibly
739  // corresponding to this CM hit)
740  // already in the collection
741  } // end of if reduceCablingOverlap
742 
743  if (solvePhiAmb_thisHit && !etaview){
744  ATH_MSG_VERBOSE("nMatchingEtaHits = " << nMatchingEtaHits
745  << " hasAMatchingEtaHit = "<< hasAMatchingEtaHit);
746  }
747  if (duplicate) {
748  // this hit was already recorded
749  ATH_MSG_DEBUG("digit already in the collection ");
750  continue;
751  }
752  ATH_MSG_VERBOSE(" solvePhiAmb_thisHit: "<<solvePhiAmb_thisHit<<", processingetaview:"<<processingetaview
753  <<", processingphiview: "<<processingphiview<<", hasAMatchingEtaHit: "<<hasAMatchingEtaHit
754  <<", unsolvedAmbiguity: "<< unsolvedAmbiguity);
755  if ( !solvePhiAmb_thisHit || processingetaview ||
756  (processingphiview && (hasAMatchingEtaHit || unsolvedAmbiguity))) {
757  if (unsolvedAmbiguity) {
758  if (idVect.empty()) { // full-scan mode
759  ATH_MSG_DEBUG("storing data even if unsolvedAmbiguity");
760  } else {
761  // if in RoI mode and the collection was not requested in this
762  // event, add it to ambiguousCollections
763  ATH_MSG_DEBUG("unsolvedAmbiguity is true, adding collection with hash = "
764  << rpcHashId << " to ambiguous collections vector");
765  const auto& decode{state.m_decodedOfflineHashIds};
766  if (!decode.empty() && decode.find(rpcHashId) == decode.end()) {
767  ambiguousCollections.insert(rpcHashId);
768  ATH_MSG_DEBUG("collection not yet processed; added to ambiguous "
769  <<"collection vector; going to the next offline channel ID");
770  continue; // go to the next possible offline channel ID
771  } else if (!doingSecondLoopAmbigColls) {
772  ambiguousCollections.insert(rpcHashId);
773  ATH_MSG_DEBUG("collection already processed and doingSecondLoopAmbigColls=false; added to ambiguous "
774  <<"collection vector; going to the next offline channel ID");
775  continue;
776  } else {
777  ATH_MSG_DEBUG("collection already processed and doingSecondLoopAmbigColls=true; trying to store data even if unsolvedAmbiguity");
778  }
779  }
780  }
781  SG::ReadCondHandle muDetMgr{m_muDetMgrKey, ctx};
782  const RpcReadoutElement* descriptor = muDetMgr->getRpcReadoutElement(channelId);
783 
784  // here check validity
785  // if invalid, reset flags
786  if (!descriptor->containsId(channelId)) {
787  hasAMatchingEtaHit = false;
788  duplicate = false;
789  if (idHelper.stationNameString(idHelper.stationName(channelId)) == "BOG"){
790  ATH_MSG_DEBUG("Identifier from the cabling service <"<< m_idHelperSvc->toString(channelId)
791  << "> inconsistent with the geometry of detector element <"
792  << m_idHelperSvc->toStringDetEl(descriptor->identify())
793  << "> =>>ignore this hit /// there are unmasked channels in BOG");
794  }else{
795  ATH_MSG_WARNING("Identifier from the cabling service <"<< m_idHelperSvc->toString(channelId)
796  << "> inconsistent with the geometry of detector element <"
797  << m_idHelperSvc->toStringDetEl(descriptor->identify())<< "> =>>ignore this hit");
798  }
799  continue;
800  }
801 
802  //
803  // Global position
804  Amg::Vector3D tempGlobalPosition = descriptor->stripPos(channelId);
805  ATH_MSG_VERBOSE("RPC RDO->PrepRawdata: global position "<<Amg::toString(tempGlobalPosition));
806  // Local position
807  Amg::Vector2D pointLocPos{Amg::Vector2D::Zero()};
808  descriptor->surface(channelId).globalToLocal(tempGlobalPosition, tempGlobalPosition, pointLocPos);
809 
810  // List of Digits in the cluster (self)
811  std::vector<Identifier> identifierList{channelId};
812 
813  // width of the cluster (self)
814  float stripWidth = descriptor->StripWidth(m_idHelperSvc->rpcIdHelper().measuresPhi(channelId));
815 
816  // Error matrix
817  double errPos = stripWidth / std::sqrt(12.0);
818  Amg::MatrixX mat(1, 1);
819  mat.setIdentity();
820  mat *= errPos * errPos;
821  // check if this is a triggerINFO rather then a real hit
822  // Create a new PrepData
823  int ambiguityFlag = 0;
824  if (solvePhiAmb_thisHit) {
825  if (processingetaview){
826  ambiguityFlag = 1;
827  }
828  if (unsolvedAmbiguity){
829  ambiguityFlag = digitVec.size();
830  } else if (hasAMatchingEtaHit){
831  ambiguityFlag = nMatchingEtaHits;
832  }
833  }
834 
835  // correct prd time from cool db
836  if (m_RPCInfoFromDb) {
837  SG::ReadCondHandle readHandle{m_readKey, ctx};
838  std::optional<double> StripTimeFromCool = readHandle->getStripTime(channelId);
839  if (StripTimeFromCool) {
840  time -= (*StripTimeFromCool);
841  }
842  }
843 
844  if (triggerHit) {
845  ATH_MSG_DEBUG("producing a new RpcCoinData");
846 
847  auto newCoinData = std::make_unique<RpcCoinData>(channelId, rpcHashId,
848  std::move(pointLocPos), std::move(identifierList),
849  std::move(mat), descriptor, time,
850  ambiguityFlag, rpcChan->ijk(), threshold, overlap, cmaId, padId, sectorId,
851  !(highPtCm));
852 
853  // record the new data in the collection
854  ATH_MSG_DEBUG(" Adding RpcCoinData @ "<< newCoinData.get() << " to collection "
855  << m_idHelperSvc->toString(collectionTrg->identify()));
856 
857  newCoinData->setHashAndIndex(collectionTrg->identifyHash(),
858  collectionTrg->size());
859  collectionTrg->push_back(std::move(newCoinData));
860  } // end of to be stored now for RpcCoinData
861  else {
862  ATH_MSG_DEBUG("producing a new RpcPrepData with "
863  << "ambiguityFlag = " << ambiguityFlag);
864 
865  auto newPrepData = std::make_unique<RpcPrepData>(channelId, rpcHashId,std::move(pointLocPos),
866  std::move(identifierList),
867  std::move(mat), descriptor, time, ambiguityFlag);
868 
869  // record the new data in the collection
870  ATH_MSG_DEBUG(" Adding digit @ "<< newPrepData.get() << " to collection "
871  << m_idHelperSvc->toString(collection->identify()));
872 
873  newPrepData->setHashAndIndex(collection->identifyHash(),
874  collection->size());
875  collection->push_back(std::move(newPrepData));
876  // here one should reset ambiguityFlag for the prepdata
877  // registered before the current one (from the same RDO hit) if
878  // nMatchingEtaHits > 1
879  nPrepRawData++;
880  }
881  } // end of to be stored now
882  } // end loop over possible offline identifiers corresponding to this
883  // CM hit
884  ATH_MSG_VERBOSE("processingphiview:"<<processingphiview<<", nMatchingEtaHits:"<<nMatchingEtaHits
885  <<", nDuplicatePhiHits, unsolvedAmbiguity: "<<unsolvedAmbiguity<<", solvePhiAmb_thisHit : "
886  << solvePhiAmb_thisHit);
887  if ((processingphiview && (nMatchingEtaHits == 0)) && (nDuplicatePhiHits == 0) &&
888  (!unsolvedAmbiguity) && (solvePhiAmb_thisHit)) {
889  unsolvedAmbiguity = true;
890  // no eta hits matching any phi digit
891  // loop once again and store all phi digits potentially generating
892  // this CM hit
893  ATH_MSG_DEBUG("No eta prepData matching any phi hit from this CM hit \n"
894  << "loop once again and store all phi digits potentially "
895  "generating this CM hit");
896  } else if (unsolvedAmbiguity)
897  notFinished = false;
898  else
899  notFinished = false;
900  } // end of not finished
901  } // end loop over CM hits
902  } // end loop over CMs
903 
904  ATH_MSG_DEBUG("***************** Stop of processPad eta/phiview "
905  << processingetaview << "/" << processingphiview
906  << "***************** for Pad online Id " << padId
907  << " m_logic sector ID " << sectorId);
908 
909  return StatusCode::SUCCESS;
910 }
911 
913  State& state) const {
914  if (m_rdoNrpcContainerKey.empty()) {
915  ATH_MSG_DEBUG("The NRPC processing is disabled.");
916  return StatusCode::SUCCESS;
917  }
918 
919  ATH_MSG_DEBUG("Retrieving Nrpc RDO container from the store");
920  SG::ReadHandle rdoNrpcContainerHandle{m_rdoNrpcContainerKey, ctx};
921  if (!rdoNrpcContainerHandle.isPresent()) {
922  ATH_MSG_ERROR("Retrieval of NRPC RDO " << m_rdoNrpcContainerKey.fullKey()
923  << " container failed !");
924  return StatusCode::FAILURE;
925  }
926 
927  if (rdoNrpcContainerHandle->empty()) {
928  // empty NRPC RDO container - no nrpc rdo in this event
929  ATH_MSG_DEBUG("Empty NRPC RDO container - no nrpc rdo in this event ");
930  return StatusCode::SUCCESS;
931  }
932  ATH_MSG_DEBUG("Not empty NRPC RDO container in this event ");
933 
934  SG::ReadCondHandle readCdo{m_nRpcCablingKey, ctx};
935  if (!readCdo.isValid()) {
936  ATH_MSG_ERROR("Could not retrieve " << m_nRpcCablingKey.fullKey()
937  << " from the conditions store");
938  return StatusCode::FAILURE;
939  }
941  SG::ReadCondHandle muDetMgr{m_muDetMgrKey, ctx};
942 
943  for (const xAOD::NRPCRDO* nrpcrdo : *rdoNrpcContainerHandle) {
945  RpcCablingData translateCache{};
946  translateCache.subDetector = nrpcrdo->subdetector();
947  translateCache.boardSector = nrpcrdo->boardsector();
948  translateCache.board = nrpcrdo->board();
949  translateCache.channelId = nrpcrdo->channel();
950  Identifier chanId{};
951  if (!readCdo->getOfflineId(translateCache, msgStream()) ||
952  !readCdo->convert(translateCache, chanId, false)) {
953  // If online channel is not associated to offline, continue to decode the remaining part of the RDO
955  continue;
956  }
957 
958  RpcPrepDataCollection* collection = state.getPrepCollection(chanId);
959 
960  const RpcReadoutElement* descriptor = muDetMgr->getRpcReadoutElement(chanId);
961 
962  // List of Digits in the cluster (self)
963  std::vector<Identifier> identifierList{chanId};
964  // Global position
965  const Amg::Vector3D stripPos{descriptor->stripPos(chanId)};
966  ATH_MSG_DEBUG("RPC RDO->PrepRawdata " << m_idHelperSvc->toString(chanId)
967  << " global position "
968  << Amg::toString(stripPos, 2));
969  // Local position
970  Amg::Vector2D pointLocPos{Amg::Vector2D::Zero()};
971  descriptor->surface(chanId).globalToLocal(stripPos, stripPos, pointLocPos);
972  // width of the cluster (self)
973 
974  const double stripWidth = descriptor->StripWidth(
975  m_idHelperSvc->rpcIdHelper().measuresPhi(chanId));
976  // Error matrix
977  const double errPos = stripWidth / std::sqrt(12.0);
978  Amg::MatrixX mat(1, 1);
979  mat.setIdentity();
980  mat *= errPos * errPos;
981 
982  int ambiguityFlag = 0; // Ambiguity flag not checked for BIS RPCs
983 
984  const float time = nrpcrdo->time();
986  const float timeoverthr = nrpcrdo->timeoverthr();
987 
988  const IdentifierHash rpcHashId = m_idHelperSvc->moduleHash(chanId);
989  auto newPrepData = std::make_unique<RpcPrepData>(chanId, rpcHashId, pointLocPos, identifierList, mat,
990  descriptor, time, timeoverthr, 0, ambiguityFlag);
991 
992  newPrepData->setHashAndIndex(collection->identifyHash(),
993  collection->size());
994  collection->push_back(std::move(newPrepData));
995  }
996  return StatusCode::SUCCESS;
997 }
998 
1001  bool highPtCm, bool& triggerHit,
1002  unsigned short& threshold, unsigned short& overlap,
1003  bool& toSkip) const {
1004  toSkip = false;
1005  const RpcFiredChannel* rpcChan = (*itD);
1006  if ((highPtCm && rpcChan->ijk() < 2) || (rpcChan->ijk() > 5)) {
1007  ATH_MSG_VERBOSE("RpcFiredChannel: it's a trigger hit");
1008  triggerHit = true;
1009 
1010  // triggerHit
1012  // skip if not storing the trigger info
1013  toSkip = true;
1014  return;
1015  }
1016  if (rpcChan->ijk() == 7) {
1017  // the info in ijk 7 refer to the previous CM hit with ijk 6 => skip
1018  toSkip = true;
1019  return;
1020  }
1021  if (rpcChan->ijk() == 6) {
1022  // look for the subsequent ijk 7 to define threshold and overlap
1023  ATH_MSG_VERBOSE("This hit: ijk = " << rpcChan->ijk() << "in "<<(highPtCm ? "high" : "low")
1024  <<" pT CM, bcid is " << rpcChan->bcid()<< " time is " << rpcChan->time()
1025  << " ch " << rpcChan->channel());
1026  RpcCoinMatrix::const_iterator itDnext = itD + 1;
1027  while (itDnext != itD_end) {
1028  const RpcFiredChannel* rpcChanNext = (*itDnext);
1029  ATH_MSG_VERBOSE("Next hit: ijk = " << rpcChanNext->ijk() << "in "<<(highPtCm ? "high" : "low")
1030  <<" pT CM, bcid is " << rpcChan->bcid() << " time is " << rpcChanNext->time()
1031  <<", ch: "<<( rpcChanNext->ijk() < 7? rpcChanNext->channel() : -1));
1032 
1033  if (rpcChanNext->ijk() == 7) {
1034  if (rpcChanNext->bcid() == rpcChan->bcid() && rpcChanNext->time() == rpcChan->time()) {
1035  ATH_MSG_VERBOSE("bdid/tick match; assigning thr/overlap = " << rpcChanNext->thr() << "/" << rpcChanNext->ovl());
1036  threshold = rpcChanNext->thr();
1037  overlap = rpcChanNext->ovl();
1038  } else {
1039  ATH_MSG_WARNING("ijk =7 after a ijk = 6 BUT bdid/tick don't match - will not assign threshold/overlap ");
1040  }
1041  break;
1042  } else {
1043  if (rpcChanNext->ijk() == 6) {
1044  ++itDnext;
1045  // std::cout<<"next has ijk 6; try next to next"<<std::endl;
1046  } else {
1047  ATH_MSG_WARNING("RPC cm hit with ijk = 6 not followed by ijk = 6 or 7 - will not assign threshold / overlap");
1048  break;
1049  }
1050  }
1051  }
1052  }
1053  } else {
1054  triggerHit = false;
1055  return;
1056  }
1057  ATH_MSG_VERBOSE("RPC trigger hit; ijk = "
1058  << rpcChan->ijk() << " threshold / overlap = " << threshold
1059  << "/" << overlap);
1060 }
1061 }
RpcFiredChannel::ijk
ubit16 ijk() const
Definition: RpcFiredChannel.h:56
IRPC_RDO_Decoder.h
RpcCoinDataContainer.h
Trk::PlaneSurface::globalToLocal
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...
Definition: PlaneSurface.cxx:209
RpcIdHelper::parentID
Identifier parentID(const Identifier &id) const
Definition: RpcIdHelper.cxx:994
RpcFiredChannel::time
ubit16 time() const
Definition: RpcFiredChannel.h:54
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
Muon::RpcRdoToPrepDataToolMT::m_reduceCablingOverlap
Gaudi::Property< bool > m_reduceCablingOverlap
Definition: RpcRdoToPrepDataToolMT.h:130
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
RpcFiredChannel::ovl
ubit16 ovl() const
Definition: RpcFiredChannel.h:61
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
RpcFiredChannel::thr
ubit16 thr() const
Definition: RpcFiredChannel.h:65
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Muon::RpcCablingOnlineID::subDetector
int16_t & subDetector
Identifier of the subdetector region in the readout BA / BC etc.
Definition: RpcCablingData.h:82
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Surface.h
RpcFiredChannel::channel
ubit16 channel() const
Definition: RpcFiredChannel.h:58
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
Muon::RpcRdoToPrepDataToolMT::provideEmptyContainer
virtual StatusCode provideEmptyContainer(const EventContext &ctx) const override
Definition: RpcRdoToPrepDataToolMT.cxx:154
Muon::RpcRdoToPrepDataToolMT::State::m_fullEventDone
bool m_fullEventDone
Definition: RpcRdoToPrepDataToolMT.h:67
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:55
Muon::RpcRdoToPrepDataToolMT::finalize
virtual StatusCode finalize() override
Definition: RpcRdoToPrepDataToolMT.cxx:83
Muon::RpcRdoToPrepDataToolMT::processPad
StatusCode processPad(const EventContext &ctx, State &state, const RpcPad *rdoColl, bool &processingetaview, bool &processingphiview, int &nPrepRawData, const std::vector< IdentifierHash > &idVect, bool doingSecondLoopAmbigColls) const
Definition: RpcRdoToPrepDataToolMT.cxx:546
RpcIdHelper::measuresPhi
bool measuresPhi(const Identifier &id) const override
Definition: RpcIdHelper.cxx:1064
Muon::MuonCoinDataCollection
Definition: MuonCoinDataCollection.h:25
Muon::RpcRdoToPrepDataToolMT::initialize
virtual StatusCode initialize() override
Definition: RpcRdoToPrepDataToolMT.cxx:49
Muon::RpcRdoToPrepDataToolMT::m_stripTimeResolution
Gaudi::Property< double > m_stripTimeResolution
Definition: RpcRdoToPrepDataToolMT.h:185
MuonGM::RpcReadoutElement
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/RpcReadoutElement.h:55
Muon::RpcRdoToPrepDataToolMT::m_rdoNrpcContainerKey
SG::ReadHandleKey< xAOD::NRPCRDOContainer > m_rdoNrpcContainerKey
Definition: RpcRdoToPrepDataToolMT.h:158
Muon::RpcRdoToPrepDataToolMT::m_RPCInfoFromDb
Gaudi::Property< bool > m_RPCInfoFromDb
correct time prd from cool db
Definition: RpcRdoToPrepDataToolMT.h:137
xAOD::NRPCRDO_v1
Definition: NRPCRDO_v1.h:14
Muon::RpcRdoToPrepDataToolMT::decode
virtual StatusCode decode(const EventContext &ctx, const std::vector< IdentifierHash > &idVect) const override
This code is thread-safe as we will propagate local thread collection contents to a thread-safe one.
Definition: RpcRdoToPrepDataToolMT.cxx:121
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
MuonIdHelper::stationName
int stationName(const Identifier &id) const
Definition: MuonIdHelper.cxx:810
MuonPrepDataContainer.h
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
Muon::RpcRdoToPrepDataToolMT::State::getPrepCollection
RpcPrepDataCollection * getPrepCollection(const Identifier &id)
Definition: RpcRdoToPrepDataToolMT.cxx:27
Muon
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition: TrackSystemController.h:45
xAOD::RpcStrip_v1
Definition: RpcStrip_v1.h:11
Muon::RpcRdoToPrepDataToolMT::decodeImpl
StatusCode decodeImpl(const EventContext &ctx, State &state, const std::vector< IdentifierHash > &idVect, bool firstTimeInTheEvent) const
Definition: RpcRdoToPrepDataToolMT.cxx:262
RpcCoinMatrix
Definition: RpcCoinMatrix.h:20
MuonGM::MuonClusterReadoutElement::surface
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
Definition: MuonClusterReadoutElement.h:123
RpcIdHelper
Definition: RpcIdHelper.h:51
RpcFiredChannel
Definition: RpcFiredChannel.h:20
Muon::RpcRdoToPrepDataToolMT::m_xAODKey
SG::WriteHandleKey< xAOD::RpcStripContainer > m_xAODKey
Definition: RpcRdoToPrepDataToolMT.h:180
Muon::RpcRdoToPrepDataToolMT::m_rpcCoinDataContainerKey
SG::WriteHandleKey< RpcCoinDataContainer > m_rpcCoinDataContainerKey
RpcCoinData containers.
Definition: RpcRdoToPrepDataToolMT.h:152
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
Muon::RpcRdoToPrepDataToolMT::m_coindataContainerCacheKey
SG::UpdateHandleKey< RpcCoinDataCollection_Cache > m_coindataContainerCacheKey
Definition: RpcRdoToPrepDataToolMT.h:176
Muon::RpcRdoToPrepDataToolMT::m_timeShift
Gaudi::Property< float > m_timeShift
Definition: RpcRdoToPrepDataToolMT.h:132
Muon::RpcRdoToPrepDataToolMT::m_rpcReadKey
SG::ReadCondHandleKey< RpcCablingCondData > m_rpcReadKey
Definition: RpcRdoToPrepDataToolMT.h:167
Muon::RpcRdoToPrepDataToolMT::State
Definition: RpcRdoToPrepDataToolMT.h:48
Muon::MuonPrepDataCollection::identifyHash
virtual IdentifierHash identifyHash() const override final
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Muon::RpcRdoToPrepDataToolMT::m_prdContainerCacheKey
SG::UpdateHandleKey< RpcPrepDataCollection_Cache > m_prdContainerCacheKey
This is the key for the cache for the MDT PRD containers, can be empty.
Definition: RpcRdoToPrepDataToolMT.h:173
Muon::RpcRdoToPrepDataToolMT::State::m_decodedRobIds
std::unordered_set< uint32_t > m_decodedRobIds
Definition: RpcRdoToPrepDataToolMT.h:78
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
Muon::RpcRdoToPrepDataToolMT::processTriggerHitHypothesis
void processTriggerHitHypothesis(RpcCoinMatrix::const_iterator itD, RpcCoinMatrix::const_iterator itD_end, bool highptpad, bool &triggerHit, unsigned short &threshold, unsigned short &overlap, bool &toSkip) const
Definition: RpcRdoToPrepDataToolMT.cxx:999
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Muon::RpcRdoToPrepDataToolMT::m_rpcPrepDataContainerKey
SG::WriteHandleKey< RpcPrepDataContainer > m_rpcPrepDataContainerKey
RpcPrepData containers.
Definition: RpcRdoToPrepDataToolMT.h:149
MuonR4::State
CalibratedSpacePoint::State State
Definition: SpacePointCalibrator.cxx:42
IdentifiableContainerMT::IDC_WriteHandle
Definition: IdentifiableContainerMT.h:35
Muon::RpcRdoToPrepDataToolMT::State::rpcPrepDataCollections
std::vector< std::unique_ptr< RpcPrepDataCollection > > rpcPrepDataCollections
Definition: RpcRdoToPrepDataToolMT.h:57
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Muon::RpcRdoToPrepDataToolMT::State::coinDataCont
std::unique_ptr< RpcCoinDataContainer > coinDataCont
Pointer of the coin container stored in store gate.
Definition: RpcRdoToPrepDataToolMT.h:63
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
Muon::MuonPrepDataCollection
Template to hold collections of MuonPrepRawData objects.
Definition: MuonPrepDataCollection.h:46
CaloCondBlobAlgs_fillNoiseFromASCII.channelId
channelId
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:121
Muon::RpcRdoToPrepDataToolMT::m_muDetMgrKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_muDetMgrKey
Definition: RpcRdoToPrepDataToolMT.h:141
RpcPad::onlineId
ubit16 onlineId() const
Definition: RpcPad.h:107
xAOD::MeasVector
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
Definition: MeasurementDefs.h:53
Muon::RpcRdoToPrepDataToolMT::transferAndRecordPrepData
StatusCode transferAndRecordPrepData(const EventContext &ctx, State &state) const
Stores the PrepData container into store gate.
Definition: RpcRdoToPrepDataToolMT.cxx:162
MuonIdHelper::stationNameString
const std::string & stationNameString(const int &index) const
Definition: MuonIdHelper.cxx:864
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Muon::RpcCablingData
Helper struct that is parsed to the cabling map to translate between the offline & online Identifiers...
Definition: RpcCablingData.h:96
IDC_Helper.h
MuonGM::RpcReadoutElement::containsId
virtual bool containsId(const Identifier &id) const override
function to be used to check whether a given Identifier is contained in the readout element
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:423
Muon::RpcRdoToPrepDataToolMT::State::prepDataCont
std::unique_ptr< RpcPrepDataContainer > prepDataCont
Pointer of the prep container stored in store gate.
Definition: RpcRdoToPrepDataToolMT.h:61
Muon::RpcRdoToPrepDataToolMT::m_readKey
SG::ReadCondHandleKey< RpcCondDbData > m_readKey
Definition: RpcRdoToPrepDataToolMT.h:165
Muon::RpcRdoToPrepDataToolMT::m_etaphi_coincidenceTime
Gaudi::Property< float > m_etaphi_coincidenceTime
3 ns is the resolution of the RPC readout electronics
Definition: RpcRdoToPrepDataToolMT.h:118
Muon::RpcRdoToPrepDataToolMT::transferAndRecordCoinData
StatusCode transferAndRecordCoinData(const EventContext &ctx, State &state) const
Stores the CoinData container into store gate.
Definition: RpcRdoToPrepDataToolMT.cxx:223
Muon::RpcRdoToPrepDataToolMT::State::m_ambiguousCollections
std::unordered_set< IdentifierHash > m_ambiguousCollections
Definition: RpcRdoToPrepDataToolMT.h:75
Muon::RpcRdoToPrepDataToolMT::m_producePRDfromTriggerWords
Gaudi::Property< bool > m_producePRDfromTriggerWords
Definition: RpcRdoToPrepDataToolMT.h:124
MuonGM::RpcReadoutElement::stripPos
Amg::Vector3D stripPos(const Identifier &id) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:177
threshold
Definition: chainparser.cxx:74
SG::UpdateHandle
Definition: UpdateHandle.h:91
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
RpcPad::identifyHash
IdentifierHash identifyHash() const
Returns the OFFLINE identifier hash for this collection.
Definition: RpcPad.h:103
Muon::RpcRdoToPrepDataToolMT::m_decodeData
Gaudi::Property< bool > m_decodeData
toggle on/off the decoding of RPC RDO into RpcPerpData
Definition: RpcRdoToPrepDataToolMT.h:134
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RpcPad
Definition: RpcPad.h:21
Muon::MuonCoinDataCollection::identifyHash
IdentifierHash identifyHash() const
MuonGM::RpcReadoutElement::StripWidth
double StripWidth(bool measphi) const
returns the strip width for the phi or eta plane
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
Muon::RpcRdoToPrepDataToolMT::m_overlap_timeTolerance
Gaudi::Property< float > m_overlap_timeTolerance
Definition: RpcRdoToPrepDataToolMT.h:121
RpcFiredChannel::bcid
ubit16 bcid() const
Definition: RpcFiredChannel.h:52
Muon::RpcRdoToPrepDataToolMT::m_idHelperSvc
ServiceHandle< IMuonIdHelperSvc > m_idHelperSvc
Definition: RpcRdoToPrepDataToolMT.h:145
RpcPad::sector
int sector() const
Definition: RpcPad.h:112
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
xAOD::parentId
@ parentId
Definition: TrackingPrimitives.h:517
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Muon::RpcRdoToPrepDataToolMT::m_rpcRdoDecoderTool
ToolHandle< IRPC_RDO_Decoder > m_rpcRdoDecoderTool
Definition: RpcRdoToPrepDataToolMT.h:162
DEBUG
#define DEBUG
Definition: page_access.h:11
MuonGM::MuonReadoutElement::identify
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonReadoutElement.h:173
Muon::RpcRdoToPrepDataToolMT::State::rpcCoinDataCollections
std::vector< std::unique_ptr< RpcCoinDataCollection > > rpcCoinDataCollections
Definition: RpcRdoToPrepDataToolMT.h:58
Muon::RpcRdoToPrepDataToolMT::State::getCoinCollection
RpcCoinDataCollection * getCoinCollection(const Identifier &id)
Definition: RpcRdoToPrepDataToolMT.cxx:37
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:27
Muon::RpcRdoToPrepDataToolMT::loadProcessedChambers
StatusCode loadProcessedChambers(const EventContext &ctx, State &state) const
Load the hashes of the processed chambers.
Definition: RpcRdoToPrepDataToolMT.cxx:87
IdentifierByDetElSorter.h
xAOD::MeasMatrix
Eigen::Matrix< float, N, N > MeasMatrix
Definition: MeasurementDefs.h:55
Muon::IdentifierByDetElSorter
Definition: IdentifierByDetElSorter.h:17
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Muon::RpcRdoToPrepDataToolMT::State::m_decodedOfflineHashIds
std::unordered_set< IdentifierHash > m_decodedOfflineHashIds
Definition: RpcRdoToPrepDataToolMT.h:71
RpcRdoToPrepDataToolMT.h
Muon::RpcRdoToPrepDataToolMT::m_nRpcCablingKey
SG::ReadCondHandleKey< RpcCablingMap > m_nRpcCablingKey
Definition: RpcRdoToPrepDataToolMT.h:169
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:27
RpcStripAuxContainer.h
Muon::RpcRdoToPrepDataToolMT::m_rdoContainerKey
SG::ReadHandleKey< RpcPadContainer > m_rdoContainerKey
Definition: RpcRdoToPrepDataToolMT.h:155
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.
Muon::RpcRdoToPrepDataToolMT::processNrpcRdo
StatusCode processNrpcRdo(const EventContext &ctx, State &state) const
15 ns should be the max.diff.
Definition: RpcRdoToPrepDataToolMT.cxx:912
Muon::RpcRdoToPrepDataToolMT::m_solvePhiAmbiguities
Gaudi::Property< bool > m_solvePhiAmbiguities
Definition: RpcRdoToPrepDataToolMT.h:127
Muon::RpcRdoToPrepDataToolMT::m_isMC
Gaudi::Property< bool > m_isMC
Definition: RpcRdoToPrepDataToolMT.h:139
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
Muon::RpcRdoToPrepDataToolMT::m_spuriousHitCounter
std::atomic_int m_spuriousHitCounter
Definition: RpcRdoToPrepDataToolMT.h:189
RpcReadoutElement.h
Identifier
Definition: IdentifierFieldParser.cxx:14