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