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