7 #include "GaudiKernel/ThreadLocalContext.h"
16 #include "GeoModelKernel/throwExcept.h"
22 m_idHelperSvc{idHelperSvc} {
23 const IdentifierHash hashMax =
m_idHelperSvc->rpcIdHelper().module_hash_max();
24 rpcPrepDataCollections.resize(hashMax);
25 rpcCoinDataCollections.resize(hashMax);
29 const IdentifierHash rpdModHash =
m_idHelperSvc->moduleHash(chanId);
30 std::unique_ptr<RpcPrepDataCollection>& coll = rpcPrepDataCollections[rpdModHash];
32 coll = std::make_unique<RpcPrepDataCollection>(rpdModHash);
38 const IdentifierHash rpdModHash =
m_idHelperSvc->moduleHash(chanId);
39 std::unique_ptr<RpcCoinDataCollection>& coll = rpcCoinDataCollections[rpdModHash];
41 coll = std::make_unique<RpcCoinDataCollection>(rpdModHash);
58 ATH_MSG_WARNING(
"Inconsistent setting of properties (solvePhiAmbiguities entails reduceCablingOverlap)");
81 return StatusCode::SUCCESS;
85 return StatusCode::SUCCESS;
88 const int modHashMax =
m_idHelperSvc->rpcIdHelper().module_hash_max();
91 if (!update.isValid()) {
93 return StatusCode::FAILURE;
95 state.
prepDataCont = std::make_unique<RpcPrepDataContainer>(update.ptr());
100 state.
prepDataCont = std::make_unique<RpcPrepDataContainer>(modHashMax);
104 state.
coinDataCont = std::make_unique<RpcCoinDataContainer>(modHashMax);
108 if (!update.isValid()) {
110 return StatusCode::FAILURE;
112 state.
coinDataCont = std::make_unique<RpcCoinDataContainer>(update.ptr());
117 return StatusCode::SUCCESS;
122 const std::vector<IdentifierHash>& idVect)
const {
123 ATH_MSG_DEBUG(
"Calling Core decode function from MT decode function (hash vector)");
129 ATH_MSG_DEBUG(
"Core decode processed in MT decode (hash vector)");
134 return StatusCode::SUCCESS;
140 const std::vector<uint32_t>& robIds)
const {
141 ATH_MSG_DEBUG(
"Calling Core decode function from MT decode function (ROB vector)");
147 ATH_MSG_DEBUG(
"Core decode processed in MT decode (ROB vector)");
152 return StatusCode::SUCCESS;
159 return StatusCode::SUCCESS;
167 ATH_CHECK(writeHandleXAOD.record(std::make_unique<xAOD::RpcStripContainer>(),
168 std::make_unique<xAOD::RpcStripAuxContainer>()));
172 if (!collection || collection->empty()) {
178 std::vector<const RpcPrepData*> sortMe{collection->begin(), collection->end()};
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());
191 strip->setTriggerInfo(prd->triggerInfo());
194 strip->setMeasurement(
m_idHelperSvc->detElementHash(
id), std::move(locPos), std::move(locCov));
198 const IdentifierHash
hash = collection->identifyHash();
201 if (
lock.alreadyPresent()) {
202 ATH_MSG_DEBUG(
"RpcPrepDataCollection already contained in IDC "
220 return StatusCode::SUCCESS;
225 return StatusCode::SUCCESS;
230 if (!collection || collection->empty()) {
233 const IdentifierHash
hash = collection->identifyHash();
236 if (
lock.alreadyPresent()) {
237 ATH_MSG_DEBUG(
"RpcCoinDataCollection already contained in IDC "
258 return StatusCode::SUCCESS;
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){
272 std::vector<IdentifierHash> idVectToBeDecoded;
273 idVectToBeDecoded.reserve(idVect.size());
275 if (firstTimeInTheEvent) {
279 ATH_MSG_DEBUG(
"Whole event has already been decoded; nothing to do.");
280 return StatusCode::SUCCESS;
282 if (sizeVectorRequested == 0) {
287 if (sizeVectorRequested != 0) {
291 for (
const IdentifierHash& itHashId : idVect) {
293 idVectToBeDecoded.push_back(itHashId);
296 if (idVectToBeDecoded.empty()) {
297 ATH_MSG_DEBUG(
"All requested offline collections have already been decoded; nothing to do.");
298 return StatusCode::SUCCESS;
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);
308 ATH_MSG_DEBUG(
"Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
309 return StatusCode::SUCCESS;
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));
327 ATH_MSG_DEBUG(
"Retrieving Rpc PAD container from the store");
329 if (!rdoContainerHandle.isValid()) {
331 return StatusCode::FAILURE;
336 if (rdoContainerHandle->numberOfCollections() == 0) {
338 ATH_MSG_DEBUG(
"Empty pad container - no rpc rdo in this event ");
339 return StatusCode::SUCCESS;
345 bool doingSecondLoopAmbigColls =
false;
347 int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
348 if (processingphiview) {
351 ATH_MSG_DEBUG(
"*** Processing "<<(processingetaview ?
"eta" :
"phi")<<
" view ");
353 if (sizeVectorRequested != 0) {
355 for (
const IdentifierHash& iPadHash : rdoHashVec) {
356 const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(iPadHash);
358 ATH_MSG_DEBUG(
"Requested pad with online id "<< iPadHash <<
" not found in the rdoContainerHandle.");
364 <<
", with " << rdoColl->
size() <<
" CM inside ");
366 processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
371 for (
const RpcPad* rdoColl : *rdoContainerHandle) {
373 if (rdoColl->empty()){
377 ATH_MSG_DEBUG(
"A new pad here n. " << ipad <<
", online id "<< rdoColl->identifyHash()
378 <<
", with " << rdoColl->size() <<
" CM inside ");
381 processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
385 if (processingetaview) {
386 processingetaview =
false;
387 processingphiview =
true;
388 nEtaPrepRawData = nPrepRawData;
389 ATH_MSG_DEBUG(
"*** " << nEtaPrepRawData <<
" eta PrepRawData registered");
391 processingphiview =
false;
392 nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
393 ATH_MSG_DEBUG(
"*** " << nPhiPrepRawData <<
" phi PrepRawData registered");
396 doingSecondLoopAmbigColls =
true;
397 processingetaview =
true;
399 idVectToBeDecoded.clear();
403 idVectToBeDecoded.push_back(itAmbiColl);
406 ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
410 ATH_MSG_DEBUG(
"*** " << nPrepRawData <<
" PrepRawData registered");
416 return StatusCode::SUCCESS;
421 const std::vector<uint32_t>& robIds,
bool firstTimeInTheEvent)
const {
425 int sizeVectorRequested = robIds.size();
426 ATH_MSG_DEBUG(
"Decode method called for " << sizeVectorRequested <<
" ROBs");
428 std::vector<uint32_t> robIdsToBeDecoded{};
429 robIdsToBeDecoded.reserve(robIds.size());
431 if (firstTimeInTheEvent) {
435 ATH_MSG_DEBUG(
"Whole event has already been decoded; nothing to do.");
436 return StatusCode::SUCCESS;
443 robIdsToBeDecoded.push_back(robid);
447 if (robIdsToBeDecoded.empty()) {
448 ATH_MSG_DEBUG(
"All requested ROBs have already been decoded; nothing to do.");
449 return StatusCode::SUCCESS;
451 ATH_MSG_DEBUG(robIdsToBeDecoded.size()<<
" ROBs have not yet been decoded and will be decoded now.");
454 for (
uint32_t robid : robIdsToBeDecoded)
462 if (state.
m_decodedRobIds.size() == rpcCabling->giveFullListOfRobIds().size())
467 ATH_MSG_DEBUG(
"Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
468 return StatusCode::SUCCESS;
474 ATH_MSG_DEBUG(
"Retrieving Rpc PAD container from the store");
476 if (!rdoContainerHandle.isValid()) {
478 return StatusCode::SUCCESS;
483 if (rdoContainerHandle->empty()) {
485 ATH_MSG_DEBUG(
"Empty pad container - no rpc rdo in this event ");
486 return StatusCode::SUCCESS;
491 std::vector<IdentifierHash> rdoHashVec;
492 rdoHashVec.reserve(13 * robIdsToBeDecoded.size());
493 ATH_CHECK(rpcCabling->giveRDO_fromROB(robIdsToBeDecoded, rdoHashVec));
496 bool processingetaview =
true;
497 bool processingphiview =
false;
499 processingetaview =
false;
502 int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
503 if (processingphiview){
506 ATH_MSG_DEBUG(
"*** Processing "<<(processingetaview?
"eta" :
"phi")<<
" view ");
511 for (
const IdentifierHash& padHashId : rdoHashVec) {
512 const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(padHashId);
514 ATH_MSG_DEBUG(
"Requested pad with online id "<< padHashId <<
" not found in the rdoContainerHandle.");
519 <<
", with " << rdoColl->
size() <<
" CM inside ");
521 processingphiview, nPrepRawData, rdoHashVec,
false));
524 if (processingetaview) {
525 processingetaview =
false;
526 processingphiview =
true;
527 nEtaPrepRawData = nPrepRawData;
528 ATH_MSG_DEBUG(
"*** " << nEtaPrepRawData <<
" eta PrepRawData registered");
530 processingphiview =
false;
531 nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
532 ATH_MSG_DEBUG(
"*** " << nPhiPrepRawData <<
" phi PrepRawData registered");
535 ATH_MSG_DEBUG(
"*** " << nPrepRawData <<
" PrepRawData registered");
542 return StatusCode::SUCCESS;
547 bool& processingetaview,
bool& processingphiview,
int& nPrepRawData,
548 const std::vector<IdentifierHash>& idVect,
549 bool doingSecondLoopAmbigColls)
const {
554 ATH_MSG_DEBUG(
"***************** Start of processPad eta/phiview "<< processingetaview <<
"/" << processingphiview);
559 ATH_MSG_DEBUG(
"***************** for Pad online Id "<< padId <<
" m_logic sector ID " << sectorId);
566 IdentifierHash rpcHashId{0};
575 bool highPtCm =
false;
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());
583 }
else if (cmaId >=4) {
589 ATH_MSG_DEBUG(
" eta view = " << etaview<<
", processingetaview: "<<processingetaview
590 <<
", processingphiview: "<<processingphiview);
592 if (processingetaview && !etaview){
594 }
else if (processingphiview && etaview) {
597 if (coinMat->empty()) {
607 unsigned short overlap = 99;
614 ATH_MSG_DEBUG(
"RpcFiredChannel: bcid " << rpcChan->bcid() <<
" time " << rpcChan->time()
615 <<
" ijk "<< rpcChan->ijk() <<
" ch " << ( rpcChan->ijk() < 7 ? rpcChan->channel() : -1));
618 bool triggerHit =
false;
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);
637 std::vector<Identifier> digitVec{
m_rpcRdoDecoderTool->getOfflineData(rpcChan, sectorId, padId,
638 cmaId,
time, rpcCabling.cptr())};
641 int nMatchingEtaHits{0}, nDuplicatePhiHits{0};
642 bool unsolvedAmbiguity{
false}, notFinished{
true};
651 while (notFinished) {
653 ATH_MSG_DEBUG(
"size of the corresponding list of ID = " << digitVec.size());
654 if (digitVec.empty()) {
668 if (!idVect.empty() &&
std::find(idVect.begin(), idVect.end(), rpcHashId) == idVect.end()) {
673 bool hasAMatchingEtaHit = 0;
676 if ((oldIdTrg !=
parentId) || !collectionTrg) {
680 <<
" hash = " << rpcHashId);
685 }
else if ((oldId !=
parentId) || !collection) {
697 bool duplicate =
false;
698 if (reduceCablOvl_thisHit) {
699 ATH_MSG_VERBOSE(
"Check for duplicates in coll. with size "<< collection->size());
705 hasAMatchingEtaHit =
false;
709 float previous_time = rpc->time();
711 if (
time < previous_time) {
713 ATH_MSG_DEBUG(
"time of the prd previously stored is now updated with "
714 <<
"current hit time: "<< previous_time <<
" -> " << rpc->time());
722 if (processingphiview && solvePhiAmb_thisHit && !unsolvedAmbiguity && !idHelper.
measuresPhi(existId) &&
725 hasAMatchingEtaHit =
true;
733 if (hasAMatchingEtaHit)
737 if (processingphiview && duplicate)
743 if (solvePhiAmb_thisHit && !etaview){
745 <<
" hasAMatchingEtaHit = "<< hasAMatchingEtaHit);
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()) {
763 ATH_MSG_DEBUG(
"unsolvedAmbiguity is true, adding collection with hash = "
764 << rpcHashId <<
" to ambiguous collections vector");
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");
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");
777 ATH_MSG_DEBUG(
"collection already processed and doingSecondLoopAmbigColls=true; trying to store data even if unsolvedAmbiguity");
787 hasAMatchingEtaHit =
false;
791 <<
"> inconsistent with the geometry of detector element <"
793 <<
"> =>>ignore this hit /// there are unmasked channels in BOG");
796 <<
"> inconsistent with the geometry of detector element <"
811 std::vector<Identifier> identifierList{
channelId};
817 double errPos = stripWidth / std::sqrt(12.0);
820 mat *= errPos * errPos;
823 int ambiguityFlag = 0;
824 if (solvePhiAmb_thisHit) {
825 if (processingetaview){
828 if (unsolvedAmbiguity){
829 ambiguityFlag = digitVec.size();
830 }
else if (hasAMatchingEtaHit){
831 ambiguityFlag = nMatchingEtaHits;
838 std::optional<double> StripTimeFromCool = readHandle->getStripTime(
channelId);
839 if (StripTimeFromCool) {
840 time -= (*StripTimeFromCool);
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,
854 ATH_MSG_DEBUG(
" Adding RpcCoinData @ "<< newCoinData.get() <<
" to collection "
857 newCoinData->setHashAndIndex(collectionTrg->identifyHash(),
858 collectionTrg->size());
859 collectionTrg->push_back(std::move(newCoinData));
863 <<
"ambiguityFlag = " << ambiguityFlag);
865 auto newPrepData = std::make_unique<RpcPrepData>(
channelId, rpcHashId,std::move(pointLocPos),
866 std::move(identifierList),
867 std::move(
mat), descriptor,
time, ambiguityFlag);
870 ATH_MSG_DEBUG(
" Adding digit @ "<< newPrepData.get() <<
" to collection "
873 newPrepData->setHashAndIndex(collection->identifyHash(),
875 collection->push_back(std::move(newPrepData));
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;
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)
904 ATH_MSG_DEBUG(
"***************** Stop of processPad eta/phiview "
905 << processingetaview <<
"/" << processingphiview
906 <<
"***************** for Pad online Id " << padId
907 <<
" m_logic sector ID " << sectorId);
909 return StatusCode::SUCCESS;
913 State& state)
const {
916 return StatusCode::SUCCESS;
919 ATH_MSG_DEBUG(
"Retrieving Nrpc RDO container from the store");
921 if (!rdoNrpcContainerHandle.isPresent()) {
923 <<
" container failed !");
924 return StatusCode::FAILURE;
927 if (rdoNrpcContainerHandle->empty()) {
929 ATH_MSG_DEBUG(
"Empty NRPC RDO container - no nrpc rdo in this event ");
930 return StatusCode::SUCCESS;
932 ATH_MSG_DEBUG(
"Not empty NRPC RDO container in this event ");
935 if (!readCdo.isValid()) {
937 <<
" from the conditions store");
938 return StatusCode::FAILURE;
943 for (
const xAOD::NRPCRDO* nrpcrdo : *rdoNrpcContainerHandle) {
946 translateCache.
subDetector = nrpcrdo->subdetector();
947 translateCache.boardSector = nrpcrdo->boardsector();
948 translateCache.board = nrpcrdo->board();
949 translateCache.channelId = nrpcrdo->channel();
951 if (!readCdo->getOfflineId(translateCache, msgStream()) ||
952 !readCdo->convert(translateCache, chanId,
false)) {
963 std::vector<Identifier> identifierList{chanId};
967 <<
" global position "
974 const double stripWidth = descriptor->
StripWidth(
977 const double errPos = stripWidth / std::sqrt(12.0);
980 mat *= errPos * errPos;
982 int ambiguityFlag = 0;
984 const float time = nrpcrdo->time();
986 const float timeoverthr = nrpcrdo->timeoverthr();
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);
992 newPrepData->setHashAndIndex(collection->
identifyHash(),
994 collection->
push_back(std::move(newPrepData));
996 return StatusCode::SUCCESS;
1001 bool highPtCm,
bool& triggerHit,
1002 unsigned short&
threshold,
unsigned short& overlap,
1003 bool& toSkip)
const {
1006 if ((highPtCm && rpcChan->
ijk() < 2) || (rpcChan->
ijk() > 5)) {
1016 if (rpcChan->
ijk() == 7) {
1021 if (rpcChan->
ijk() == 6) {
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());
1027 while (itDnext != itD_end) {
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));
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());
1037 overlap = rpcChanNext->
ovl();
1039 ATH_MSG_WARNING(
"ijk =7 after a ijk = 6 BUT bdid/tick don't match - will not assign threshold/overlap ");
1043 if (rpcChanNext->
ijk() == 6) {
1047 ATH_MSG_WARNING(
"RPC cm hit with ijk = 6 not followed by ijk = 6 or 7 - will not assign threshold / overlap");
1058 << rpcChan->
ijk() <<
" threshold / overlap = " <<
threshold