ATLAS Offline Software
RpcRdoToPrepDataToolMT.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "GaudiKernel/ThreadLocalContext.h"
13 #include "TrkSurfaces/Surface.h"
16 #include "GeoModelHelpers/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 
49  const std::string& name,
50  const IInterface* parent)
51  : base_class(type, name, parent) {}
52 
53 //___________________________________________________________________________
55  // perform necessary one-off initialization
56 
57  ATH_MSG_INFO("properties are ");
58  ATH_MSG_INFO("produceRpcCoinDatafromTriggerWords " << m_producePRDfromTriggerWords);
59  ATH_MSG_INFO("reduceCablingOverlap " << m_reduceCablingOverlap);
60  ATH_MSG_INFO("solvePhiAmbiguities " << m_solvePhiAmbiguities);
61  ATH_MSG_INFO("timeShift " << m_timeShift);
64  "Inconsistent setting of properties (solvePhiAmbiguities entails "
65  "reduceCablingOverlap)");
66  ATH_MSG_WARNING("Resetting reduceCablingOverlap to true");
68  }
69  ATH_MSG_INFO("etaphi_coincidenceTime "
71  ATH_MSG_INFO("overlap_timeTolerance "
73  ATH_MSG_INFO("Correct prd time from cool db " << m_RPCInfoFromDb);
74  ATH_CHECK(m_rpcRdoDecoderTool.retrieve());
75  ATH_CHECK(m_idHelperSvc.retrieve());
81  // If we don't configure the NRPC RDO
82  // key, the cabling is needed either.
89  ATH_CHECK(m_xAODKey.initialize(!m_xAODKey.empty()));
90  return StatusCode::SUCCESS;
91 }
93  const EventContext& ctx, State& state) const {
94  if (!m_prdContainerCacheKey.key().empty()) {
96  ctx};
97  if (!update.isValid()) {
98  ATH_MSG_FATAL("Invalid UpdateHandle " << m_prdContainerCacheKey.key());
99  return StatusCode::FAILURE;
100  }
101  state.prepDataCont =
102  std::make_unique<RpcPrepDataContainer>(update.ptr());
103  for (const RpcPrepDataCollection* coll : *state.prepDataCont) {
104  state.m_decodedOfflineHashIds.insert(coll->identifyHash());
105  }
106  } else
107  state.prepDataCont = std::make_unique<RpcPrepDataContainer>(
108  m_idHelperSvc->rpcIdHelper().module_hash_max());
109 
110  if (m_coindataContainerCacheKey.key().empty()) {
111  // without the cache we just record the container
112  state.coinDataCont = std::make_unique<RpcCoinDataContainer>(
113  m_idHelperSvc->rpcIdHelper().module_hash_max());
114  } else {
115  // use the cache to get the container
118  if (!update.isValid()) {
119  ATH_MSG_FATAL("Invalid UpdateHandle "
120  << m_coindataContainerCacheKey.key());
121  return StatusCode::FAILURE;
122  }
123  state.coinDataCont =
124  std::make_unique<RpcCoinDataContainer>(update.ptr());
125  for (const RpcCoinDataCollection* coll : *state.coinDataCont) {
126  state.m_decodedOfflineHashIds.insert(coll->identifyHash());
127  }
128  }
129 
130  return StatusCode::SUCCESS;
131 }
135  const std::vector<IdentifierHash>& idVect) const {
136  ATH_MSG_DEBUG("Calling Core decode function from MT decode function (hash vector)");
137  State state{m_idHelperSvc.get()};
138  ATH_CHECK(loadProcessedChambers(ctx, state));
139 
140  ATH_CHECK(decodeImpl(ctx, state, idVect, true));
141  ATH_CHECK(processNrpcRdo(ctx, state));
142  ATH_MSG_DEBUG("Core decode processed in MT decode (hash vector)");
143 
146 
147  return StatusCode::SUCCESS;
148 }
149 
153  const std::vector<uint32_t>& robIds) const {
155  "Calling Core decode function from MT decode function (ROB vector)");
156  State state{m_idHelperSvc.get()};
157  ATH_CHECK(loadProcessedChambers(ctx, state));
158 
159  ATH_CHECK(decodeImpl(ctx, state, robIds, true));
160  ATH_CHECK(processNrpcRdo(ctx, state));
161  ATH_MSG_DEBUG("Core decode processed in MT decode (ROB vector)");
162 
165 
166  return StatusCode::SUCCESS;
167 }
169  State state{m_idHelperSvc.get()};
170  ATH_CHECK(loadProcessedChambers(ctx, state));
173  return StatusCode::SUCCESS;
174 }
175 
177 
179  if (!m_xAODKey.empty()) {
180  writeHandleXAOD = SG::WriteHandle{m_xAODKey, ctx};
181  ATH_CHECK(writeHandleXAOD.record(std::make_unique<xAOD::RpcStripContainer>(),
182  std::make_unique<xAOD::RpcStripAuxContainer>()));
183  }
184  const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
185  for (std::unique_ptr<RpcPrepDataCollection>& collection : state.rpcPrepDataCollections) {
186  if (!collection || collection->empty()) {
187  continue;
188  }
189  if (!m_xAODKey.empty()) {
192  std::vector<const RpcPrepData*> sortMe{collection->begin(), collection->end()};
193  std::ranges::sort(sortMe, IdentifierByDetElSorter{m_idHelperSvc.get()});
194  for (const RpcPrepData* prd : sortMe) {
195  const Identifier id = prd->identify();
196  xAOD::RpcStrip* strip = writeHandleXAOD->push_back(std::make_unique<xAOD::RpcStrip>());
197  strip->setDoubletPhi(idHelper.doubletPhi(id));
198  strip->setGasGap(idHelper.gasGap(id));
199  strip->setMeasuresPhi(idHelper.measuresPhi(id));
200  strip->setStripNumber(idHelper.channel(id));
201  strip->setAmbiguityFlag(prd->ambiguityFlag());
202  strip->setTimeOverThreshold(prd->timeOverThreshold());
203  strip->setTime(prd->time());
204  strip->setTimeCovariance(std::pow(m_stripTimeResolution, 2));
205  strip->setTriggerInfo(prd->triggerInfo());
206  xAOD::MeasVector<1> locPos{prd->localPosition().x()};
207  xAOD::MeasMatrix<1> locCov{prd->localCovariance()(0,0)};
208  strip->setMeasurement(m_idHelperSvc->detElementHash(id), std::move(locPos), std::move(locCov));
209  }
210  }
211 
212  const IdentifierHash hash = collection->identifyHash();
213  // If not present, get a write lock for the hash and move collection
214  RpcPrepDataContainer::IDC_WriteHandle lock = state.prepDataCont->getWriteHandle(hash);
215  if (lock.alreadyPresent()) {
216  ATH_MSG_DEBUG("RpcPrepDataCollection already contained in IDC "
217  << m_idHelperSvc->toString(collection->identify()));
218  continue;
219  }
220  ATH_CHECK(lock.addOrDelete(std::move(collection)));
221  ATH_MSG_DEBUG("PRD hash " << hash << " has been moved to cache container");
222  }
223  state.rpcPrepDataCollections.clear();
224 
225  if (msgLvl(MSG::DEBUG)) {
226  for (const auto& [hash, ptr] : state.prepDataCont->GetAllHashPtrPair()) {
227  ATH_MSG_DEBUG("Contents of CONTAINER in this view : " << hash);
228  }
229  }
231  ATH_CHECK(rpcPRDHandle.record(std::move(state.prepDataCont)));
232  ATH_MSG_DEBUG("Created container " << m_rpcPrepDataContainerKey.key());
233 
234  return StatusCode::SUCCESS;
235 }
236 
238  const EventContext& ctx, State& state) const {
240  return StatusCode::SUCCESS;
241  }
242 
243  // Take localContainer and transfer contents to rpcCoinHandle
244  for (std::unique_ptr<RpcCoinDataCollection>& collection : state.rpcCoinDataCollections) {
245  if (!collection || collection->empty()) {
246  continue;
247  }
248  const IdentifierHash hash = collection->identifyHash();
249  // If not present, get a write lock for the hash and move collection
250  RpcCoinDataContainer::IDC_WriteHandle lock = state.coinDataCont->getWriteHandle(hash);
251  if (lock.alreadyPresent()) {
252  ATH_MSG_DEBUG("RpcCoinDataCollection already contained in IDC "
253  << m_idHelperSvc->toString(collection->identify()));
254  continue;
255  }
256  ATH_CHECK(lock.addOrDelete(std::move(collection)));
257  ATH_MSG_DEBUG("Coin hash " << hash << " has been moved to cache container");
258  }
259  state.rpcCoinDataCollections.clear();
260  if (msgLvl(MSG::DEBUG)) {
261  for (const auto& [hash, ptr] : state.coinDataCont->GetAllHashPtrPair()) {
262  ATH_MSG_DEBUG("Contents of LOCAL in this view : " << hash);
263  }
264  }
267  ATH_CHECK(rpcCoinHandle.record(std::move(state.coinDataCont)));
268 
269  ATH_MSG_DEBUG("Created container " << m_rpcCoinDataContainerKey.key());
270  // For additional information on the contents of the cache-based container,
271  // this function can be used printMTCoinData (*rpcCoinHandle);
272 
273  return StatusCode::SUCCESS;
274 }
275 
276 //___________________________________________________________________________
278  State& state,
279  const std::vector<IdentifierHash>& idVect,
280  bool firstTimeInTheEvent) const {
281  int sizeVectorRequested = idVect.size();
282  ATH_MSG_DEBUG("Decode method called for " << sizeVectorRequested
283  << " offline collections");
284  if (sizeVectorRequested == 0)
285  ATH_MSG_DEBUG("Decoding the entire event");
286 
287  // create an empty vector of hash ids to be decoded (will be filled if
288  // RoI-based and left empty if full-scan)
289  std::vector<IdentifierHash> idVectToBeDecoded;
290  idVectToBeDecoded.reserve(idVect.size());
291 
292  if (firstTimeInTheEvent) {
293  state.m_fullEventDone = sizeVectorRequested == 0;
294  } else {
295  if (state.m_fullEventDone) {
296  ATH_MSG_DEBUG("Whole event has already been decoded; nothing to do.");
297  return StatusCode::SUCCESS;
298  }
299  if (sizeVectorRequested == 0)
300  state.m_fullEventDone = true;
301  }
302 
303  if (sizeVectorRequested != 0) {
304  // the program goes in here only if RoI-based decoding has been called and
305  // the full event is not already decoded this code ensures decoding of every
306  // offline hash id is called only once
307  for (const IdentifierHash& itHashId : idVect) {
308  if (state.m_decodedOfflineHashIds.insert(itHashId).second)
309  idVectToBeDecoded.push_back(itHashId);
310  }
311  if (idVectToBeDecoded.empty()) {
313  "All requested offline collections have already been decoded; "
314  "nothing to do.");
315  return StatusCode::SUCCESS;
316  } else {
317  ATH_MSG_DEBUG(idVectToBeDecoded.size()
318  << " offline collections have not yet been decoded and "
319  "will be decoded now.");
320  if (msgLvl(MSG::VERBOSE)) {
322  "The list of offline collection hash ids to be decoded:");
323  for (const IdentifierHash& itHashId : idVectToBeDecoded)
324  ATH_MSG_VERBOSE(itHashId << " ");
325  }
326  }
327  }
328 
329  // if RPC decoding is switched off stop here
330  if (!m_decodeData) {
332  "Stored empty container. Decoding RPC RDO into RPC PrepRawData is "
333  "switched off");
334  return StatusCode::SUCCESS;
335  }
336 
337  ATH_MSG_DEBUG("Decoding RPC RDO into RPC PrepRawData");
338 
340  const RpcCablingCondData* rpcCabling{*cablingCondData};
341 
342  // if the vector requested has size 0, we need to perform a scan of the entire
343  // RDO container otherwise select the pads to be decoded
344  std::vector<IdentifierHash> rdoHashVec;
345  if (sizeVectorRequested != 0) {
347  "Looking for pads IdHash to be decoded for the requested collection "
348  "Ids");
349  ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
350  }
351 
353  IdContext rpcContext = m_idHelperSvc->rpcIdHelper().module_context();
354 
355  // we come here if the rdo container is already in SG (for example in MC RDO!)
356  ATH_MSG_DEBUG("Retrieving Rpc PAD container from the store");
357  auto rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
358  if (!rdoContainerHandle.isValid()) {
359  ATH_MSG_ERROR("Retrieval of RPC RDO container failed !");
360  return StatusCode::FAILURE;
361  }
362 
365  if (rdoContainerHandle->numberOfCollections() == 0) {
366  // empty pad container - no rpc rdo in this event
367  ATH_MSG_DEBUG("Empty pad container - no rpc rdo in this event ");
368  return StatusCode::SUCCESS;
369  }
370  ATH_MSG_DEBUG("Not empty pad container in this event ");
371 
372  // start here to process the RDO (for the full event of for a fraction of it)
373  bool processingetaview{true}, processingphiview{false};
375  processingetaview = false;
376  bool doingSecondLoopAmbigColls = false;
377  while (processingetaview || processingphiview || (!m_solvePhiAmbiguities)) {
378  int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
379  if (processingphiview)
380  state.m_ambiguousCollections.clear();
381  if (msgLvl(MSG::DEBUG)) {
382  if (processingetaview)
383  ATH_MSG_DEBUG("*** Processing eta view ");
384  else
385  ATH_MSG_DEBUG("*** Processing phi view ");
386  }
387  // seeded decoding
388  if (sizeVectorRequested != 0) {
389  ATH_MSG_DEBUG("Start loop over pads hashes - seeded mode ");
390  for (const IdentifierHash& iPadHash : rdoHashVec) {
391  const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(iPadHash);
392  if (!rdoColl) {
393  ATH_MSG_DEBUG("Requested pad with online id "
394  << iPadHash << " not found in the rdoContainerHandle.");
395  continue;
396  }
397  ++ipad;
398 
399  ATH_MSG_DEBUG("A new pad here n. " << ipad << ", online id "
400  << (int)(rdoColl->identifyHash())
401  << ", with " << rdoColl->size()
402  << " CM inside ");
403  ATH_CHECK(processPad(ctx, state, rdoColl, processingetaview,
404  processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
405 
406  } // end loop over requested pads hashes
407  } else { // unseeded // whole event
408  ATH_MSG_DEBUG("Start loop over pads - unseeded mode ");
409  for (const RpcPad* rdoColl : *rdoContainerHandle) {
410  // loop over all elements of the pad container
411  if (rdoColl->empty())
412  continue;
413  ++ipad;
414  ATH_MSG_DEBUG("A new pad here n. " << ipad << ", online id "
415  << (int)(rdoColl->identifyHash())
416  << ", with " << rdoColl->size()
417  << " CM inside ");
418 
419  ATH_CHECK(processPad(ctx, state, rdoColl, processingetaview,
420  processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
421  } // end loop over pads
422  }
423 
424  if (processingetaview) {
425  processingetaview = false;
426  processingphiview = true;
427  nEtaPrepRawData = nPrepRawData;
428  ATH_MSG_DEBUG("*** " << nEtaPrepRawData << " eta PrepRawData registered");
429  } else {
430  processingphiview = false;
431  nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
432  ATH_MSG_DEBUG("*** " << nPhiPrepRawData << " phi PrepRawData registered");
433  if (!state.m_ambiguousCollections.empty()) {
434  // loop again for unrequested collections stored with ambiguous phi hits
435  doingSecondLoopAmbigColls = true;
436  processingetaview = true;
438  << " ambiguous collections were stored:");
439  idVectToBeDecoded.clear();
440  rdoHashVec.clear();
441  for (const IdentifierHash& itAmbiColl : state.m_ambiguousCollections) {
442  ATH_MSG_DEBUG((int)itAmbiColl << " ");
443  idVectToBeDecoded.push_back(itAmbiColl);
444  state.m_decodedOfflineHashIds.insert(itAmbiColl);
445  }
446  ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
447  }
448  }
449  if (!m_solvePhiAmbiguities) {
450  ATH_MSG_DEBUG("*** " << nPrepRawData << " PrepRawData registered");
451  break;
452  }
453  }
454 
455  ATH_MSG_DEBUG("*** Final Cleanup ");
456  return StatusCode::SUCCESS;
457 }
458 
459 //___________________________________________________________________________
461  const EventContext& ctx, State& state, const std::vector<uint32_t>& robIds,
462  bool firstTimeInTheEvent) const {
463  // ROB-based decoding is only applied in seeded mode. Full scan should use the
464  // hashId-based method with empty requested collections vector.
465 
466  int sizeVectorRequested = robIds.size();
467  ATH_MSG_DEBUG("Decode method called for " << sizeVectorRequested << " ROBs");
468 
469  std::vector<uint32_t> robIdsToBeDecoded;
470  robIdsToBeDecoded.reserve(robIds.size());
471 
472  if (firstTimeInTheEvent) {
473  state.m_fullEventDone = false;
474  } else {
475  if (state.m_fullEventDone) {
476  ATH_MSG_DEBUG("Whole event has already been decoded; nothing to do.");
477  return StatusCode::SUCCESS;
478  }
479  }
480 
481  // check which of the requested robs are not yet decoded
482  for (uint32_t robid : robIds) {
483  if (state.m_decodedRobIds.insert(robid).second)
484  robIdsToBeDecoded.push_back(robid);
485  }
486 
487  if (robIdsToBeDecoded.empty()) {
489  "All requested ROBs have already been decoded; nothing to do.");
490  return StatusCode::SUCCESS;
491  }
492  ATH_MSG_DEBUG(robIdsToBeDecoded.size()
493  << " ROBs have not yet been decoded and will be decoded now.");
494  if (msgLvl(MSG::VERBOSE)) {
495  ATH_MSG_VERBOSE("The list of ROB Ids to be decoded:");
496  for (uint32_t robid : robIdsToBeDecoded)
497  ATH_MSG_VERBOSE("0x" << MSG::hex << robid << MSG::dec << " ");
498  }
499 
501  const RpcCablingCondData* rpcCabling{*cablingCondData};
502 
503  // if all robs will be decoded after the current execution of the method, set
504  // the flag m_fullEventDone
505  if (state.m_decodedRobIds.size() == rpcCabling->giveFullListOfRobIds().size())
506  state.m_fullEventDone = true;
507 
508  // if RPC decoding is switched off stop here
509  if (!m_decodeData) {
511  "Stored empty container. Decoding RPC RDO into RPC PrepRawData is "
512  "switched off");
513  return StatusCode::SUCCESS;
514  }
515 
516  ATH_MSG_DEBUG("Decoding RPC RDO into RPC PrepRawData");
517 
518  // we come here if the rdo container is already in SG (for example in MC RDO!)
519  ATH_MSG_DEBUG("Retrieving Rpc PAD container from the store");
520  auto rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
521  if (!rdoContainerHandle.isValid()) {
522  ATH_MSG_WARNING("Retrieval of RPC RDO container failed !");
523  return StatusCode::SUCCESS;
524  }
525 
526  // here the RDO container is retrieved and filled -whatever input type we
527  // start with- => check the size
528  if (rdoContainerHandle->empty()) {
529  // empty pad container - no rpc rdo in this event
530  ATH_MSG_DEBUG("Empty pad container - no rpc rdo in this event ");
531  return StatusCode::SUCCESS;
532  }
533  ATH_MSG_DEBUG("Not empty pad container in this event ");
534 
535  // obtain a list of PADs (RDOs) to be processed
536  std::vector<IdentifierHash> rdoHashVec;
537  rdoHashVec.reserve(
538  13 * robIdsToBeDecoded.size()); // most ROBs have 13 RDOs, some have less
539  ATH_CHECK(rpcCabling->giveRDO_fromROB(robIdsToBeDecoded, rdoHashVec));
540 
541  // start here to process the RDOs
542  bool processingetaview = true;
543  bool processingphiview = false;
545  processingetaview = false;
546  while (processingetaview || processingphiview || (!m_solvePhiAmbiguities)) {
547  int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
548  if (processingphiview)
549  state.m_ambiguousCollections.clear();
550 
551  if (processingetaview)
552  ATH_MSG_DEBUG("*** Processing eta view ");
553  else
554  ATH_MSG_DEBUG("*** Processing phi view ");
555 
556  // seeded decoding (for full scan, use the hashId-based method)
557  ATH_MSG_DEBUG("Start loop over pads hashes - seeded mode ");
558 
559  for (const IdentifierHash& padHashId : rdoHashVec) {
560  const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(padHashId);
561  if (!rdoColl) {
562  ATH_MSG_DEBUG("Requested pad with online id "
563  << (unsigned int)padHashId
564  << " not found in the rdoContainerHandle.");
565  continue;
566  }
567  ++ipad;
568  ATH_MSG_DEBUG("A new pad here n."
569  << ipad << ", online id " << (int)(rdoColl->identifyHash())
570  << ", with " << rdoColl->size() << " CM inside ");
571  CHECK(processPad(ctx, state, rdoColl, processingetaview,
572  processingphiview, nPrepRawData, rdoHashVec, false));
573  }
574 
575  if (processingetaview) {
576  processingetaview = false;
577  processingphiview = true;
578  nEtaPrepRawData = nPrepRawData;
579  ATH_MSG_DEBUG("*** " << nEtaPrepRawData << " eta PrepRawData registered");
580  } else {
581  processingphiview = false;
582  nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
583  ATH_MSG_DEBUG("*** " << nPhiPrepRawData << " phi PrepRawData registered");
584  }
585  if (!m_solvePhiAmbiguities) {
586  ATH_MSG_DEBUG("*** " << nPrepRawData << " PrepRawData registered");
587  break;
588  }
589  }
590 
591  ATH_MSG_DEBUG("*** Final Cleanup ");
592 
593  return StatusCode::SUCCESS;
594 
595 }
596 
598  const EventContext& ctx, State& state, const RpcPad* rdoColl,
599  bool& processingetaview, bool& processingphiview, int& nPrepRawData,
600  const std::vector<IdentifierHash>& idVect,
601  bool doingSecondLoopAmbigColls) const {
602 
603  const RpcIdHelper& idHelper = m_idHelperSvc->rpcIdHelper();
604 
605  std::unordered_set<IdentifierHash>& ambiguousCollections{state.m_ambiguousCollections};
606  ATH_MSG_DEBUG("***************** Start of processPad eta/phiview "
607  << processingetaview << "/" << processingphiview);
608  //{processPad
609  // Get pad online id and sector id
610  uint16_t padId = rdoColl->onlineId();
611  uint16_t sectorId = rdoColl->sector();
612  ATH_MSG_DEBUG("***************** for Pad online Id "
613  << padId << " m_logic sector ID " << sectorId);
614 
615  // Create an RPC PrepDataCollection
616  Identifier oldId{0}, oldIdTrg{0};
617  ATH_MSG_VERBOSE("Init pointer to RpcPrepDataCollection ");
618  RpcPrepDataCollection* collection{nullptr};
619  RpcCoinDataCollection* collectionTrg{nullptr};
620  IdentifierHash rpcHashId{0};
621 
623 
624  // For each pad, loop on the coincidence matrices
625  RpcPad::const_iterator itCM = rdoColl->begin();
626  RpcPad::const_iterator itCM_e = rdoColl->end();
627  int icm = 0;
629  for (; itCM != itCM_e; ++itCM) {
630  icm++;
631  bool etaview = false;
632  if (!evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION))
633  etaview = true;
634  bool highPtCm = false;
635  // Get CM online Id
636  uint16_t cmaId = (*itCM)->onlineId();
637  ATH_MSG_DEBUG("A new CM here n. "
638  << icm << " CM online ID " << cmaId
639  << " with n. of hits = " << (*itCM)->size());
640  if (cmaId < 4) {
641  ATH_MSG_DEBUG(" low pt ");
642  if (cmaId < 2) {
643  etaview = true;
644  if (!evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
645  etaview = false;
646  }
647  ATH_MSG_DEBUG(" eta view = " << etaview);
648  }
649 
650  else {
651  ATH_MSG_DEBUG(" eta view = " << etaview);
652  }
653  } else {
654  ATH_MSG_DEBUG(" high pt ");
655  highPtCm = true;
656  if (cmaId < 6) {
657  etaview = true;
658  if (!evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
659  etaview = false;
660  }
661  ATH_MSG_DEBUG(" eta view = " << etaview);
662  } else {
663  ATH_MSG_DEBUG(" eta view = " << etaview);
664  }
665  }
666 
667  if (processingetaview && (!etaview))
668  continue;
669  if (processingphiview && etaview)
670  continue;
671 
672  // For each CM, loop on the fired channels
673  RpcCoinMatrix::const_iterator itD = (*itCM)->begin();
674  RpcCoinMatrix::const_iterator itD_e = (*itCM)->end();
675  int idata = 0;
676  if (itD == itD_e) {
677  ATH_MSG_DEBUG("Empty CM");
678  }
679  for (; itD != itD_e; ++itD) {
680  idata++;
681  // trigger related quantities
682  unsigned short threshold = 99;
683  unsigned short overlap = 99;
684 
685  // flags defining the processing mode of this hit
686  bool solvePhiAmb_thisHit = m_solvePhiAmbiguities;
687  bool reduceCablOvl_thisHit = m_reduceCablingOverlap;
688 
689  ATH_MSG_DEBUG("A new CM Hit " << idata);
690  const RpcFiredChannel* rpcChan = (*itD);
691  if (msgLvl(MSG::DEBUG)) {
692  ATH_MSG_DEBUG("RpcFiredChannel: bcid " << rpcChan->bcid() << " time "
693  << rpcChan->time() << " ijk "
694  << rpcChan->ijk());
695  if (rpcChan->ijk() < 7)
696  ATH_MSG_DEBUG(" ch " << rpcChan->channel());
697  }
698 
699  // check if trigger hit
700  // select the cases: ijk = 0 and high p, ijk= 6, ijk=7
701  bool triggerHit = false;
702  bool toSkip = false;
703  processTriggerHitHypothesis(itD, itD_e, highPtCm, triggerHit, threshold,
704  overlap, toSkip);
705  if (toSkip)
706  continue;
707  if (triggerHit) {
708  // here ijk = 6 or ijk = 0 in high pt cm
709  // keep all pivot + trigger info (even if duplicated [should never
710  // happen, for pivot hits])
711  solvePhiAmb_thisHit = false;
712  reduceCablOvl_thisHit = false;
714  "RpcFiredChannel: it's a triggerHit or a lowPt coinc. in a high pt "
715  "CM \n"
716  << " ijk = " << rpcChan->ijk() << " isHighPtCM " << highPtCm
717  << " thr/ovl = " << threshold << "/" << overlap);
718  }
719 
720  // here decode (get offline ids for the online indices of this hit)
721  double time = 0.;
722  std::vector<Identifier> digitVec{m_rpcRdoDecoderTool->getOfflineData(
723  rpcChan, sectorId, padId, cmaId, time, rpcCabling.cptr())};
724  time += (double)m_timeShift;
725 
726  int nMatchingEtaHits = 0;
727  int nDuplicatePhiHits = 0;
728  bool unsolvedAmbiguity = false;
729  bool notFinished = true;
730  // allow for 2 iterations in case there are phi digits without matching
731  // eta (eta inefficiency) all eta digits, not already recorded, will be
732  // registered as PrepRawData and all phi digits, not yet recorded and with
733  // a eta digit in the same module and gap, will produce a PrepRawData. Phi
734  // digits without a eta match will not be recorded at the first iteration.
735  // If all phi digits do not have a eta match, they will be all recorded as
736  // PrepRawData in the second iteration (the ambiguity will remain
737  // unsolved)
738  while (notFinished) {
739  // Loop on the digits corresponding to the fired channel
741  "size of the corresponding list of ID = " << digitVec.size());
742  if (digitVec.empty()) {
743  ATH_MSG_DEBUG("going to next CM hit");
744  notFinished = false;
745  continue;
746  }
747  for (const Identifier& channelId : digitVec) {
748  // Prepare the prepdata for this identifier
749  // channel Id
750  rpcHashId = m_idHelperSvc->moduleHash(channelId);
751  const Identifier parentId = idHelper.parentID(channelId);
752 
753  // There is some ambiguity in the channel/sectorId's, so need to
754  // explicitly filter out hashIDs outside of the RoI in seeded decoding
755  // mode
756  if (!idVect.empty() &&
757  std::find(idVect.begin(), idVect.end(), rpcHashId) == idVect.end()) {
758  continue;
759  }
760  ATH_MSG_DEBUG("CM Hit decoded into offline Id "
761  << m_idHelperSvc->toString(channelId) << " time "
762  << time);
763  ATH_MSG_DEBUG(" oldID = " << m_idHelperSvc->toString(oldId) <<
764  " oldIDtrg = " << m_idHelperSvc->toString(oldIdTrg));
765  bool hasAMatchingEtaHit = 0;
766  // current collection has Id "parentId"; get it from the container !
767  if (triggerHit) {
768  if ((oldIdTrg != parentId) || !collectionTrg) {
769  // Get collection from IDC if it exists, or create it and add it
770  // if not.
771  ATH_MSG_DEBUG(" Looking/Creating a collection with ID = "
772  << m_idHelperSvc->toString(parentId) << " hash = "
773  << static_cast<unsigned int>(rpcHashId));
774  collectionTrg = state.getCoinCollection(parentId);
775  oldIdTrg = parentId;
776  ATH_MSG_DEBUG(" Resetting oldIDtrg to current parentID = "
777  << m_idHelperSvc->toString(oldIdTrg));
778  }
779  } else if ((oldId != parentId) || !collection) {
780  // Get collection from IDC if it exists, or create it and add it if
781  // not.
782  ATH_MSG_DEBUG(" Looking/Creating a collection with ID = "
783  << m_idHelperSvc->toString(parentId) << " hash = "
784  << static_cast<unsigned int>(rpcHashId));
785  collection = state.getPrepCollection(parentId);
786  oldId = parentId;
787  ATH_MSG_DEBUG(" Resetting oldID to current parentID = "
788  << m_idHelperSvc->toString(oldId));
789  }
790 
791  // check if the data has already been recorded
792  // (if you want to reduce the redundancy due to cabling overlap and if
793  // the collection is not empty)
794  bool duplicate = false;
795  if (reduceCablOvl_thisHit) {
796  if (collection->begin() != collection->end()) {
797  RpcPrepDataCollection::iterator it_rpcPrepData;
798  ATH_MSG_VERBOSE("Check for duplicates in coll. with size "
799  << collection->size());
800  int current_dbphi{0}, current_dbz{0}, current_gg{0};
801  if (processingphiview) {
802  current_dbphi =
803  m_idHelperSvc->rpcIdHelper().doubletPhi(channelId);
804  current_dbz = m_idHelperSvc->rpcIdHelper().doubletZ(channelId);
805  current_gg = m_idHelperSvc->rpcIdHelper().gasGap(channelId);
807  "Check also for eta hits matching dbz, dbphi, gg "
808  << current_dbz << " " << current_dbphi << " "
809  << current_gg);
810  }
811 
812  for (RpcPrepData* rpc : *collection) {
813  if (channelId == rpc->identify() &&
814  fabs(time - rpc->time()) < m_overlap_timeTolerance) {
815  duplicate = true;
816  hasAMatchingEtaHit = false; // we don't want to increment the
817  // number of strips with
818  // a matching eta due to a cabling overlap
819  ATH_MSG_VERBOSE("Duplicated RpcPrepData(not recorded) = "
820  << m_idHelperSvc->toString(channelId));
821  float previous_time = rpc->time();
822  // choose the smallest time within timeTolerance
823  if (time < previous_time) {
824  rpc->m_time = time;
826  "time of the prd previously stored is now updated with "
827  "current hit time: "
828  << previous_time << " -> " << rpc->time());
829  }
830  break; // this break is why we cannot have
831  // solvePhiAmb_thisHit = true and
832  // reduceCablOvl_thisHit= false
833  }
834  if (processingphiview) {
835  if (solvePhiAmb_thisHit) {
836  if (!unsolvedAmbiguity) {
837  if (m_idHelperSvc->rpcIdHelper().measuresPhi(
838  rpc->identify()) == 0) {
839  // check if there's a eta hit in the same gap
840  // of the RPC module (doubletZ, doubletPhi, gg)
841  if (current_dbz ==
842  m_idHelperSvc->rpcIdHelper().doubletZ(
843  rpc->identify())) {
844  if (current_dbphi ==
845  m_idHelperSvc->rpcIdHelper().doubletPhi(
846  rpc->identify())) {
847  if (current_gg ==
848  m_idHelperSvc->rpcIdHelper().gasGap(
849  rpc->identify())) {
850  if (fabs(time - rpc->time()) <
852  hasAMatchingEtaHit = true;
854  "There's a matching eta hit with id "
855  << m_idHelperSvc->toString(
856  rpc->identify()));
857  // here there can be a break ? NO, we need to
858  // keep looping in order to check
859  // if this preprawdata has been already
860  // recorded (due to cabling overlaps)
861  }
862  }
863  }
864  }
865  }
866  }
867  }
868  }
869  }
870  if (hasAMatchingEtaHit)
871  nMatchingEtaHits++; // Number of phi strips (possibly
872  // corresponding to this CM hit)
873  // with a matching eta
874  if (processingphiview && duplicate)
875  nDuplicatePhiHits++; // Number of phi strips (possibly
876  // corresponding to this CM hit)
877  // already in the collection
878  } // if collection is not empty
879  } // end of if reduceCablingOverlap
880 
881  if (msgLvl(MSG::VERBOSE)) {
882  if (solvePhiAmb_thisHit && (!etaview))
883  ATH_MSG_VERBOSE("nMatchingEtaHits = " << nMatchingEtaHits
884  << " hasAMatchingEtaHit = "
885  << hasAMatchingEtaHit);
886  }
887 
888  if (!duplicate) {
890  " solvePhiAmb_thisHit, processingetaview, processingphiview, "
891  "hasAMatchingEtaHit, unsolvedAmbiguity "
892  << solvePhiAmb_thisHit << " " << processingetaview << " "
893  << processingphiview << " " << hasAMatchingEtaHit << " "
894  << unsolvedAmbiguity);
895  if ((!solvePhiAmb_thisHit) || processingetaview ||
896  (processingphiview &&
897  (hasAMatchingEtaHit || unsolvedAmbiguity))) {
898  if (unsolvedAmbiguity) {
899  if (idVect.empty()) { // full-scan mode
900  ATH_MSG_DEBUG("storing data even if unsolvedAmbiguity");
901  } else {
902  // if in RoI mode and the collection was not requested in this
903  // event, add it to ambiguousCollections
905  "unsolvedAmbiguity is true, adding collection with hash "
906  "= "
907  << (int)rpcHashId << " to ambiguous collections vector");
908  if (!state.m_decodedOfflineHashIds.empty() &&
909  state.m_decodedOfflineHashIds.find(rpcHashId) ==
910  state.m_decodedOfflineHashIds.end()) {
911  ambiguousCollections.insert(rpcHashId);
913  "collection not yet processed; added to ambiguous "
914  "collection vector; going to the next offline "
915  "channel ID");
916  continue; // go to the next possible offline channel ID
917  } else if (!doingSecondLoopAmbigColls) {
918  ambiguousCollections.insert(rpcHashId);
920  "collection already processed and "
921  "doingSecondLoopAmbigColls=false; added to ambiguous "
922  "collection vector; going to the next offline channel "
923  "ID");
924  continue;
925  } else {
927  "collection already processed and "
928  "doingSecondLoopAmbigColls=true; trying to store data "
929  "even if "
930  "unsolvedAmbiguity");
931  }
932  }
933  }
935  const RpcReadoutElement* descriptor = muDetMgr->getRpcReadoutElement(channelId);
936 
937  // here check validity
938  // if invalid, reset flags
939  if (!descriptor) {
940  hasAMatchingEtaHit = false;
941  duplicate = false;
943  "Detector Element not found for Identifier from the "
944  "cabling service <"
945  << m_idHelperSvc->toString(channelId)
946  << "> =>>ignore this hit");
947  continue;
948  } else if (!descriptor->containsId(channelId)) {
949  hasAMatchingEtaHit = false;
950  duplicate = false;
951  if (m_idHelperSvc->rpcIdHelper().stationNameString(
952  m_idHelperSvc->rpcIdHelper().stationName(channelId)) ==
953  "BOG")
955  "Identifier from the cabling service <"
956  << m_idHelperSvc->toString(channelId)
957  << "> inconsistent with the geometry of detector element "
958  "<"
959  << m_idHelperSvc->toString(descriptor->identify())
960  << "> =>>ignore this hit /// there are unmasked "
961  "channels in BOG");
962  else
964  "Identifier from the cabling service <"
965  << m_idHelperSvc->toString(channelId)
966  << "> inconsistent with the geometry of detector element "
967  "<"
968  << m_idHelperSvc->toString(descriptor->identify())
969  << "> =>>ignore this hit");
970  continue;
971  }
972 
973  //
974  // Global position
975  Amg::Vector3D tempGlobalPosition =
976  descriptor->stripPos(channelId);
977  ATH_MSG_VERBOSE("RPC RDO->PrepRawdata: global position ("
978  << tempGlobalPosition.x() << ", "
979  << tempGlobalPosition.y() << ", "
980  << tempGlobalPosition.z() << ") ");
981  // Local position
982  Amg::Vector2D pointLocPos{Amg::Vector2D::Zero()};
983  descriptor->surface(channelId).globalToLocal(
984  tempGlobalPosition, tempGlobalPosition, pointLocPos);
985 
986  // List of Digits in the cluster (self)
987  std::vector<Identifier> identifierList{channelId};
988 
989  // width of the cluster (self)
990  float stripWidth = descriptor->StripWidth(
991  m_idHelperSvc->rpcIdHelper().measuresPhi(channelId));
992 
993  // Error matrix
994  double errPos = stripWidth / std::sqrt(12.0);
995  Amg::MatrixX mat(1, 1);
996  mat.setIdentity();
997  mat *= errPos * errPos;
998  // check if this is a triggerINFO rather then a real hit
999  // Create a new PrepData
1000  int ambiguityFlag = 0;
1001  if (solvePhiAmb_thisHit) {
1002  if (processingetaview)
1003  ambiguityFlag = 1;
1004  if (unsolvedAmbiguity)
1005  ambiguityFlag = digitVec.size();
1006  else if (hasAMatchingEtaHit)
1007  ambiguityFlag = nMatchingEtaHits;
1008  }
1009 
1010  // correct prd time from cool db
1011  if (m_RPCInfoFromDb) {
1013  std::optional<double> StripTimeFromCool = readHandle->getStripTime(channelId);
1014  if (StripTimeFromCool) {
1015  time -= (*StripTimeFromCool);
1016  }
1017  }
1018 
1019  if (triggerHit) {
1020  ATH_MSG_DEBUG("producing a new RpcCoinData");
1021 
1022  RpcCoinData* newCoinData = new RpcCoinData(
1023  channelId, rpcHashId, pointLocPos, identifierList,
1024  Amg::MatrixX(mat), descriptor, (float)time, ambiguityFlag,
1025  rpcChan->ijk(), threshold, overlap, cmaId, padId, sectorId,
1026  !(highPtCm));
1027 
1028  // record the new data in the collection
1029  ATH_MSG_DEBUG(
1030  " Adding RpcCoinData @ "
1031  << newCoinData << " to collection "
1032  << m_idHelperSvc->toString(collectionTrg->identify()));
1033 
1034  newCoinData->setHashAndIndex(collectionTrg->identifyHash(),
1035  collectionTrg->size());
1036  collectionTrg->push_back(newCoinData);
1037  } // end of to be stored now for RpcCoinData
1038  else {
1039  ATH_MSG_DEBUG("producing a new RpcPrepData with "
1040  << "ambiguityFlag = " << ambiguityFlag);
1041 
1042  RpcPrepData* newPrepData = new RpcPrepData(
1043  channelId, rpcHashId, pointLocPos, identifierList,
1044  Amg::MatrixX(mat), descriptor, (float)time, ambiguityFlag);
1045 
1046  // record the new data in the collection
1047  ATH_MSG_DEBUG(
1048  " Adding digit @ "
1049  << newPrepData << " to collection "
1050  << m_idHelperSvc->toString(collection->identify()));
1051 
1052  newPrepData->setHashAndIndex(collection->identifyHash(),
1053  collection->size());
1054  collection->push_back(newPrepData);
1055  // here one should reset ambiguityFlag for the prepdata
1056  // registered before the current one (from the same RDO hit) if
1057  // nMatchingEtaHits > 1
1058  nPrepRawData++;
1059  }
1060  } // end of to be stored now
1061  } // this hit was not yet recorded
1062  else {
1063  // this hit was already recorded
1064  ATH_MSG_DEBUG("digit already in the collection ");
1065  }
1066  } // end loop over possible offline identifiers corresponding to this
1067  // CM hit
1069  "processingphiview, nMatchingEtaHits, nDuplicatePhiHits, "
1070  "unsolvedAmbiguity, solvePhiAmb_thisHit : "
1071  << processingphiview << ", " << nMatchingEtaHits << ", "
1072  << nDuplicatePhiHits << ", " << unsolvedAmbiguity << ", "
1073  << solvePhiAmb_thisHit);
1074  if ((processingphiview && (nMatchingEtaHits == 0)) &&
1075  (nDuplicatePhiHits == 0) && (!unsolvedAmbiguity) &&
1076  (solvePhiAmb_thisHit)) {
1077  unsolvedAmbiguity = true;
1078  // no eta hits matching any phi digit
1079  // loop once again and store all phi digits potentially generating
1080  // this CM hit
1081  ATH_MSG_DEBUG(
1082  "No eta prepData matching any phi hit from this CM hit \n"
1083  << "loop once again and store all phi digits potentially "
1084  "generating this CM hit");
1085  } else if (unsolvedAmbiguity)
1086  notFinished = false;
1087  else
1088  notFinished = false;
1089  } // end of not finished
1090  } // end loop over CM hits
1091  } // end loop over CMs
1092 
1093  ATH_MSG_DEBUG("***************** Stop of processPad eta/phiview "
1094  << processingetaview << "/" << processingphiview
1095  << "***************** for Pad online Id " << padId
1096  << " m_logic sector ID " << sectorId);
1097 
1098  return StatusCode::SUCCESS;
1099 }
1100 
1102  State& state) const {
1103  if (m_rdoNrpcContainerKey.empty()) {
1104  ATH_MSG_DEBUG("The NRPC processing is disabled.");
1105  return StatusCode::SUCCESS;
1106  }
1107 
1108  ATH_MSG_DEBUG("Retrieving Nrpc RDO container from the store");
1109  SG::ReadHandle<xAOD::NRPCRDOContainer> rdoNrpcContainerHandle{
1110  m_rdoNrpcContainerKey, ctx};
1111  if (!rdoNrpcContainerHandle.isPresent()) {
1112  ATH_MSG_ERROR("Retrieval of NRPC RDO " << m_rdoNrpcContainerKey.fullKey()
1113  << " container failed !");
1114  return StatusCode::FAILURE;
1115  }
1116 
1117  if (rdoNrpcContainerHandle->empty()) {
1118  // empty NRPC RDO container - no nrpc rdo in this event
1119  ATH_MSG_DEBUG("Empty NRPC RDO container - no nrpc rdo in this event ");
1120  return StatusCode::SUCCESS;
1121  }
1122  ATH_MSG_DEBUG("Not empty NRPC RDO container in this event ");
1123 
1125  if (!readCdo.isValid()) {
1126  ATH_MSG_ERROR("Could not retrieve " << m_nRpcCablingKey.fullKey()
1127  << " from the conditions store");
1128  return StatusCode::FAILURE;
1129  }
1132 
1133  for (const xAOD::NRPCRDO* nrpcrdo : *rdoNrpcContainerHandle) {
1136  cabling_data.subDetector = nrpcrdo->subdetector();
1137  cabling_data.tdcSector = nrpcrdo->tdcsector();
1138  cabling_data.tdc = nrpcrdo->tdc();
1139  cabling_data.channelId = nrpcrdo->channel();
1140  Identifier chanId{};
1141  if (!readCdo->getOfflineId(cabling_data, msgStream()) ||
1142  !readCdo->convert(cabling_data, chanId, false)) {
1143  ATH_MSG_FATAL("Failed to retrieve the offline Identifier");
1144  return StatusCode::FAILURE;
1145  }
1146 
1147  RpcPrepDataCollection* collection = state.getPrepCollection(chanId);
1148 
1149  const RpcReadoutElement* descriptor =
1150  muDetMgr->getRpcReadoutElement(chanId);
1151 
1152  // List of Digits in the cluster (self)
1153  std::vector<Identifier> identifierList{chanId};
1154  // Global position
1155  const Amg::Vector3D stripPos{descriptor->stripPos(chanId)};
1156  ATH_MSG_DEBUG("RPC RDO->PrepRawdata " << m_idHelperSvc->toString(chanId)
1157  << " global position "
1158  << Amg::toString(stripPos, 2));
1159  // Local position
1160  Amg::Vector2D pointLocPos{Amg::Vector2D::Zero()};
1161  descriptor->surface(chanId).globalToLocal(stripPos, stripPos, pointLocPos);
1162  // width of the cluster (self)
1163 
1164  const double stripWidth = descriptor->StripWidth(
1165  m_idHelperSvc->rpcIdHelper().measuresPhi(chanId));
1166  // Error matrix
1167  const double errPos = stripWidth / std::sqrt(12.0);
1168  Amg::MatrixX mat(1, 1);
1169  mat.setIdentity();
1170  mat *= errPos * errPos;
1171 
1172  int ambiguityFlag = 0; // Ambiguity flag not checked for BIS RPCs
1173 
1174  const float time = nrpcrdo->time();
1176  const float timeoverthr = nrpcrdo->timeoverthr();
1177 
1178  const IdentifierHash rpcHashId = m_idHelperSvc->moduleHash(chanId);
1179  RpcPrepData* newPrepData =
1180  new RpcPrepData(chanId, rpcHashId, pointLocPos, identifierList, mat,
1181  descriptor, time, timeoverthr, 0, ambiguityFlag);
1182 
1183  newPrepData->setHashAndIndex(collection->identifyHash(),
1184  collection->size());
1185  collection->push_back(newPrepData);
1186  }
1187  return StatusCode::SUCCESS;
1188 }
1189 
1192  bool highPtCm,
1193  // the previous arg.s are inputs
1194  bool& triggerHit, unsigned short& threshold, unsigned short& overlap,
1195  bool& toSkip) const {
1196  toSkip = false;
1197  const RpcFiredChannel* rpcChan = (*itD);
1198  if ((highPtCm && rpcChan->ijk() < 2) || (rpcChan->ijk() > 5)) {
1199  ATH_MSG_VERBOSE("RpcFiredChannel: it's a trigger hit");
1200  triggerHit = true;
1201 
1202  // triggerHit
1204  // skip if not storing the trigger info
1205  toSkip = true;
1206  return;
1207  }
1208  if (rpcChan->ijk() == 7) {
1209  // the info in ijk 7 refer to the previous CM hit with ijk 6 => skip
1210  toSkip = true;
1211  return;
1212  }
1213  if (rpcChan->ijk() == 6) {
1214  std::string cmtype;
1215  // look for the subsequent ijk 7 to define threshold and overlap
1216  if (msgLvl(MSG::VERBOSE)) {
1217  cmtype = " in low pT CM ";
1218  if (highPtCm)
1219  cmtype = " in high pT CM ";
1220  ATH_MSG_VERBOSE("This hit: ijk = " << rpcChan->ijk() << cmtype
1221  << " bcid is " << rpcChan->bcid()
1222  << " time is " << rpcChan->time()
1223  << " ch " << rpcChan->channel());
1224  }
1225  RpcCoinMatrix::const_iterator itDnext = itD + 1;
1226  while (itDnext != itD_end) {
1227  const RpcFiredChannel* rpcChanNext = (*itDnext);
1228  if (msgLvl(MSG::VERBOSE)) {
1229  ATH_MSG_VERBOSE("Next hit: ijk = " << rpcChanNext->ijk() << cmtype
1230  << " bcid is " << rpcChan->bcid()
1231  << " time is "
1232  << rpcChanNext->time());
1233  if (rpcChanNext->ijk() < 7)
1234  ATH_MSG_VERBOSE(" ch " << rpcChanNext->channel());
1235  }
1236  if (rpcChanNext->ijk() == 7) {
1237  ATH_MSG_VERBOSE("next has ijk=7 ");
1238  if (rpcChanNext->bcid() == rpcChan->bcid() &&
1239  rpcChanNext->time() == rpcChan->time()) {
1240  ATH_MSG_VERBOSE("bdid/tick match; assigning thr/overlap = "
1241  << rpcChanNext->thr() << "/" << rpcChanNext->ovl());
1242  threshold = rpcChanNext->thr();
1243  overlap = rpcChanNext->ovl();
1244  } else {
1246  "ijk =7 after a ijk = 6 BUT bdid/tick don't match - will not "
1247  "assign threshold/overlap ");
1248  }
1249  break;
1250  } else {
1251  // std::cout<<"processing trigger hit with ijk = 6; next is not ijk
1252  // 7"<<std::endl;
1253  if (rpcChanNext->ijk() == 6) {
1254  ++itDnext;
1255  // std::cout<<"next has ijk 6; try next to next"<<std::endl;
1256  } else {
1258  "RPC cm hit with ijk = 6 not followed by ijk = 6 or 7 - will "
1259  "not assign threshold / overlap");
1260  break;
1261  }
1262  }
1263  }
1264  }
1265  } else {
1266  triggerHit = false;
1267  return;
1268  }
1269  ATH_MSG_VERBOSE("RPC trigger hit; ijk = "
1270  << rpcChan->ijk() << " threshold / overlap = " << threshold
1271  << "/" << overlap);
1272 }
1273 }
Muon::RpcRdoToPrepDataToolMT::m_rpcCoinDataContainerKey
SG::WriteHandleKey< Muon::RpcCoinDataContainer > m_rpcCoinDataContainerKey
RpcCoinData containers.
Definition: RpcRdoToPrepDataToolMT.h:156
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:213
RpcIdHelper::parentID
Identifier parentID(const Identifier &id) const
Definition: RpcIdHelper.cxx:997
RpcFiredChannel::time
ubit16 time() const
Definition: RpcFiredChannel.h:54
Muon::RpcRdoToPrepDataToolMT::State::rpcPrepDataCollections
std::vector< std::unique_ptr< Muon::RpcPrepDataCollection > > rpcPrepDataCollections
Definition: RpcRdoToPrepDataToolMT.h:61
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:134
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
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:70
Muon::RpcRdoToPrepDataToolMT::provideEmptyContainer
virtual StatusCode provideEmptyContainer(const EventContext &ctx) const override
Definition: RpcRdoToPrepDataToolMT.cxx:168
Muon::RpcRdoToPrepDataToolMT::State::m_fullEventDone
bool m_fullEventDone
Definition: RpcRdoToPrepDataToolMT.h:71
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:55
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
Muon::RpcRdoToPrepDataToolMT::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: RpcRdoToPrepDataToolMT.h:149
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:597
Muon::MuonCoinDataCollection
Definition: MuonCoinDataCollection.h:25
Muon::RpcRdoToPrepDataToolMT::initialize
virtual StatusCode initialize() override
Definition: RpcRdoToPrepDataToolMT.cxx:54
Muon::RpcRdoToPrepDataToolMT::m_stripTimeResolution
Gaudi::Property< double > m_stripTimeResolution
Definition: RpcRdoToPrepDataToolMT.h:192
checkFileSG.toSkip
def toSkip(inpName)
Definition: checkFileSG.py:22
Muon::RpcRdoToPrepDataToolMT::m_eventInfo
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo
Definition: RpcRdoToPrepDataToolMT.h:173
createCablingJSON.cabling_data
dictionary cabling_data
Definition: createCablingJSON.py:18
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:162
Muon::RpcRdoToPrepDataToolMT::m_RPCInfoFromDb
Gaudi::Property< bool > m_RPCInfoFromDb
correct time prd from cool db
Definition: RpcRdoToPrepDataToolMT.h:141
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:134
IdentifiableContainerMT::IDC_WriteHandle::alreadyPresent
bool alreadyPresent()
Definition: IdentifiableContainerMT.h:62
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
Muon::RpcPrepDataCollection * getPrepCollection(const Identifier &id)
Definition: RpcRdoToPrepDataToolMT.cxx:27
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:45
xAOD::RpcStrip_v1
Definition: RpcStrip_v1.h:11
Muon::RpcRdoToPrepDataToolMT::State::coinDataCont
std::unique_ptr< Muon::RpcCoinDataContainer > coinDataCont
Pointer of the coin container stored in store gate.
Definition: RpcRdoToPrepDataToolMT.h:67
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
Muon::RpcRdoToPrepDataToolMT::decodeImpl
StatusCode decodeImpl(const EventContext &ctx, State &state, const std::vector< IdentifierHash > &idVect, bool firstTimeInTheEvent) const
Definition: RpcRdoToPrepDataToolMT.cxx:277
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
Muon::RpcCoinData
Definition: RpcCoinData.h:25
RpcFiredChannel
Definition: RpcFiredChannel.h:20
Muon::RpcRdoToPrepDataToolMT::m_xAODKey
SG::WriteHandleKey< xAOD::RpcStripContainer > m_xAODKey
Definition: RpcRdoToPrepDataToolMT.h:187
RpcCablingCondData
Definition: RpcCablingCondData.h:21
Muon::RpcRdoToPrepDataToolMT::m_nRpcCablingKey
SG::ReadCondHandleKey< MuonNRPC_CablingMap > m_nRpcCablingKey
Definition: RpcRdoToPrepDataToolMT.h:175
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
Muon::RpcRdoToPrepDataToolMT::m_coindataContainerCacheKey
SG::UpdateHandleKey< RpcCoinDataCollection_Cache > m_coindataContainerCacheKey
Definition: RpcRdoToPrepDataToolMT.h:183
Muon::RpcRdoToPrepDataToolMT::m_timeShift
Gaudi::Property< float > m_timeShift
Definition: RpcRdoToPrepDataToolMT.h:136
Muon::RpcRdoToPrepDataToolMT::m_rpcReadKey
SG::ReadCondHandleKey< RpcCablingCondData > m_rpcReadKey
Definition: RpcRdoToPrepDataToolMT.h:171
Muon::RpcRdoToPrepDataToolMT::RpcRdoToPrepDataToolMT
RpcRdoToPrepDataToolMT(const std::string &, const std::string &, const IInterface *)
Definition: RpcRdoToPrepDataToolMT.cxx:48
Muon::RpcRdoToPrepDataToolMT::State
Definition: RpcRdoToPrepDataToolMT.h:52
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:180
Muon::RpcRdoToPrepDataToolMT::State::m_decodedRobIds
std::unordered_set< uint32_t > m_decodedRobIds
Definition: RpcRdoToPrepDataToolMT.h:82
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
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:1190
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
Muon::RpcRdoToPrepDataToolMT::State::rpcCoinDataCollections
std::vector< std::unique_ptr< Muon::RpcCoinDataCollection > > rpcCoinDataCollections
Definition: RpcRdoToPrepDataToolMT.h:62
Trk::PrepRawData::setHashAndIndex
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
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
NrpcCablingData
Cabling information shipped around the Digi <-> Rdo conversions.
Definition: NrpcCablingData.h:121
MuonR4::State
CalibratedSpacePoint::State State
Definition: SpacePointCalibrator.cxx:24
IdentifiableContainerMT::IDC_WriteHandle
Definition: IdentifiableContainerMT.h:34
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
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
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
Muon::MuonPrepDataCollection
Template to hold collections of MuonPrepRawData objects.
Definition: MuonPrepDataCollection.h:46
Muon::RpcRdoToPrepDataToolMT::m_rpcPrepDataContainerKey
SG::WriteHandleKey< Muon::RpcPrepDataContainer > m_rpcPrepDataContainerKey
RpcPrepData containers.
Definition: RpcRdoToPrepDataToolMT.h:153
CaloCondBlobAlgs_fillNoiseFromASCII.channelId
channelId
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:122
Muon::RpcRdoToPrepDataToolMT::m_muDetMgrKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_muDetMgrKey
Definition: RpcRdoToPrepDataToolMT.h:145
RpcPad::onlineId
ubit16 onlineId() const
Definition: RpcPad.h:107
Muon::RpcRdoToPrepDataToolMT::State::prepDataCont
std::unique_ptr< Muon::RpcPrepDataContainer > prepDataCont
Pointer of the prep container stored in store gate.
Definition: RpcRdoToPrepDataToolMT.h:65
xAOD::MeasVector
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
Definition: MeasurementDefs.h:52
Muon::RpcRdoToPrepDataToolMT::transferAndRecordPrepData
StatusCode transferAndRecordPrepData(const EventContext &ctx, State &state) const
Stores the PrepData container into store gate.
Definition: RpcRdoToPrepDataToolMT.cxx:176
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
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
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
Muon::RpcRdoToPrepDataToolMT::m_readKey
SG::ReadCondHandleKey< RpcCondDbData > m_readKey
Definition: RpcRdoToPrepDataToolMT.h:169
Muon::RpcRdoToPrepDataToolMT::m_etaphi_coincidenceTime
Gaudi::Property< float > m_etaphi_coincidenceTime
3 ns is the resolution of the RPC readout electronics
Definition: RpcRdoToPrepDataToolMT.h:122
Muon::RpcRdoToPrepDataToolMT::transferAndRecordCoinData
StatusCode transferAndRecordCoinData(const EventContext &ctx, State &state) const
Stores the CoinData container into store gate.
Definition: RpcRdoToPrepDataToolMT.cxx:237
Muon::RpcRdoToPrepDataToolMT::State::m_ambiguousCollections
std::unordered_set< IdentifierHash > m_ambiguousCollections
Definition: RpcRdoToPrepDataToolMT.h:79
Muon::RpcRdoToPrepDataToolMT::m_producePRDfromTriggerWords
Gaudi::Property< bool > m_producePRDfromTriggerWords
Definition: RpcRdoToPrepDataToolMT.h:128
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:94
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:138
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RpcPad
Definition: RpcPad.h:21
IdentifiableContainerMT::IDC_WriteHandle::addOrDelete
StatusCode addOrDelete(std::unique_ptr< T > ptr)
Definition: IdentifiableContainerMT.h:56
Muon::MuonCoinDataCollection::identifyHash
IdentifierHash identifyHash() const
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
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:76
Muon::RpcRdoToPrepDataToolMT::m_overlap_timeTolerance
Gaudi::Property< float > m_overlap_timeTolerance
Definition: RpcRdoToPrepDataToolMT.h:125
RpcFiredChannel::bcid
ubit16 bcid() const
Definition: RpcFiredChannel.h:52
RpcPad::sector
int sector() const
Definition: RpcPad.h:112
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
xAOD::parentId
@ parentId
Definition: TrackingPrimitives.h:516
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:184
Muon::RpcRdoToPrepDataToolMT::State::getCoinCollection
Muon::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:26
Muon::RpcRdoToPrepDataToolMT::loadProcessedChambers
StatusCode loadProcessedChambers(const EventContext &ctx, State &state) const
Load the hashes of the processed chambers.
Definition: RpcRdoToPrepDataToolMT.cxx:92
IdentifierByDetElSorter.h
Muon::RpcRdoToPrepDataToolMT::m_rpcRdoDecoderTool
ToolHandle< Muon::IRPC_RDO_Decoder > m_rpcRdoDecoderTool
Definition: RpcRdoToPrepDataToolMT.h:166
xAOD::MeasMatrix
Eigen::Matrix< float, N, N > MeasMatrix
Definition: MeasurementDefs.h:54
Muon::IdentifierByDetElSorter
Definition: IdentifierByDetElSorter.h:17
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
Muon::RpcRdoToPrepDataToolMT::State::m_decodedOfflineHashIds
std::unordered_set< IdentifierHash > m_decodedOfflineHashIds
Definition: RpcRdoToPrepDataToolMT.h:75
RpcRdoToPrepDataToolMT.h
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
RpcStripAuxContainer.h
Muon::RpcRdoToPrepDataToolMT::m_rdoContainerKey
SG::ReadHandleKey< RpcPadContainer > m_rdoContainerKey
Definition: RpcRdoToPrepDataToolMT.h:159
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:1101
WriteBchToCool.update
update
Definition: WriteBchToCool.py:67
Muon::RpcRdoToPrepDataToolMT::m_solvePhiAmbiguities
Gaudi::Property< bool > m_solvePhiAmbiguities
Definition: RpcRdoToPrepDataToolMT.h:131
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
RpcReadoutElement.h
Identifier
Definition: IdentifierFieldParser.cxx:14