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)");
80 return StatusCode::SUCCESS;
83 const int modHashMax =
m_idHelperSvc->rpcIdHelper().module_hash_max();
86 if (!update.isValid()) {
88 return StatusCode::FAILURE;
90 state.
prepDataCont = std::make_unique<RpcPrepDataContainer>(update.ptr());
95 state.
prepDataCont = std::make_unique<RpcPrepDataContainer>(modHashMax);
99 state.
coinDataCont = std::make_unique<RpcCoinDataContainer>(modHashMax);
103 if (!update.isValid()) {
105 return StatusCode::FAILURE;
107 state.
coinDataCont = std::make_unique<RpcCoinDataContainer>(update.ptr());
112 return StatusCode::SUCCESS;
117 const std::vector<IdentifierHash>& idVect)
const {
118 ATH_MSG_DEBUG(
"Calling Core decode function from MT decode function (hash vector)");
124 ATH_MSG_DEBUG(
"Core decode processed in MT decode (hash vector)");
129 return StatusCode::SUCCESS;
135 const std::vector<uint32_t>& robIds)
const {
136 ATH_MSG_DEBUG(
"Calling Core decode function from MT decode function (ROB vector)");
142 ATH_MSG_DEBUG(
"Core decode processed in MT decode (ROB vector)");
147 return StatusCode::SUCCESS;
154 return StatusCode::SUCCESS;
162 ATH_CHECK(writeHandleXAOD.record(std::make_unique<xAOD::RpcStripContainer>(),
163 std::make_unique<xAOD::RpcStripAuxContainer>()));
167 if (!collection || collection->empty()) {
173 std::vector<const RpcPrepData*> sortMe{collection->begin(), collection->end()};
177 xAOD::RpcStrip* strip = writeHandleXAOD->push_back(std::make_unique<xAOD::RpcStrip>());
178 strip->setDoubletPhi(idHelper.doubletPhi(
id));
179 strip->setGasGap(idHelper.gasGap(
id));
180 strip->setMeasuresPhi(idHelper.measuresPhi(
id));
181 strip->setStripNumber(idHelper.channel(
id));
182 strip->setAmbiguityFlag(prd->ambiguityFlag());
183 strip->setTimeOverThreshold(prd->timeOverThreshold());
184 strip->setTime(prd->time());
186 strip->setTriggerInfo(prd->triggerInfo());
189 strip->setMeasurement(
m_idHelperSvc->detElementHash(
id), std::move(locPos), std::move(locCov));
193 const IdentifierHash
hash = collection->identifyHash();
196 if (
lock.alreadyPresent()) {
197 ATH_MSG_DEBUG(
"RpcPrepDataCollection already contained in IDC "
215 return StatusCode::SUCCESS;
220 return StatusCode::SUCCESS;
225 if (!collection || collection->empty()) {
228 const IdentifierHash
hash = collection->identifyHash();
231 if (
lock.alreadyPresent()) {
232 ATH_MSG_DEBUG(
"RpcCoinDataCollection already contained in IDC "
253 return StatusCode::SUCCESS;
258 const std::vector<IdentifierHash>& idVect,
259 bool firstTimeInTheEvent)
const {
260 int sizeVectorRequested = idVect.size();
261 ATH_MSG_DEBUG(
"Decode method called for " << sizeVectorRequested <<
" offline collections");
262 if (sizeVectorRequested == 0){
267 std::vector<IdentifierHash> idVectToBeDecoded;
268 idVectToBeDecoded.reserve(idVect.size());
270 if (firstTimeInTheEvent) {
274 ATH_MSG_DEBUG(
"Whole event has already been decoded; nothing to do.");
275 return StatusCode::SUCCESS;
277 if (sizeVectorRequested == 0) {
282 if (sizeVectorRequested != 0) {
286 for (
const IdentifierHash& itHashId : idVect) {
288 idVectToBeDecoded.push_back(itHashId);
291 if (idVectToBeDecoded.empty()) {
292 ATH_MSG_DEBUG(
"All requested offline collections have already been decoded; nothing to do.");
293 return StatusCode::SUCCESS;
296 <<
" offline collections have not yet been decoded and will be decoded now.");
297 ATH_MSG_VERBOSE(
"The list of offline collection hash ids to be decoded:"<<std::endl<<idVectToBeDecoded);
303 ATH_MSG_DEBUG(
"Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
304 return StatusCode::SUCCESS;
312 std::vector<IdentifierHash> rdoHashVec;
313 if (sizeVectorRequested != 0) {
314 ATH_MSG_DEBUG(
"Looking for pads IdHash to be decoded for the requested collection Ids");
315 ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
322 ATH_MSG_DEBUG(
"Retrieving Rpc PAD container from the store");
324 if (!rdoContainerHandle.isValid()) {
326 return StatusCode::FAILURE;
331 if (rdoContainerHandle->numberOfCollections() == 0) {
333 ATH_MSG_DEBUG(
"Empty pad container - no rpc rdo in this event ");
334 return StatusCode::SUCCESS;
340 bool doingSecondLoopAmbigColls =
false;
342 int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
343 if (processingphiview) {
346 ATH_MSG_DEBUG(
"*** Processing "<<(processingetaview ?
"eta" :
"phi")<<
" view ");
348 if (sizeVectorRequested != 0) {
350 for (
const IdentifierHash& iPadHash : rdoHashVec) {
351 const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(iPadHash);
353 ATH_MSG_DEBUG(
"Requested pad with online id "<< iPadHash <<
" not found in the rdoContainerHandle.");
359 <<
", with " << rdoColl->
size() <<
" CM inside ");
361 processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
366 for (
const RpcPad* rdoColl : *rdoContainerHandle) {
368 if (rdoColl->empty()){
372 ATH_MSG_DEBUG(
"A new pad here n. " << ipad <<
", online id "<< rdoColl->identifyHash()
373 <<
", with " << rdoColl->size() <<
" CM inside ");
376 processingphiview, nPrepRawData, idVectToBeDecoded, doingSecondLoopAmbigColls));
380 if (processingetaview) {
381 processingetaview =
false;
382 processingphiview =
true;
383 nEtaPrepRawData = nPrepRawData;
384 ATH_MSG_DEBUG(
"*** " << nEtaPrepRawData <<
" eta PrepRawData registered");
386 processingphiview =
false;
387 nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
388 ATH_MSG_DEBUG(
"*** " << nPhiPrepRawData <<
" phi PrepRawData registered");
391 doingSecondLoopAmbigColls =
true;
392 processingetaview =
true;
394 idVectToBeDecoded.clear();
398 idVectToBeDecoded.push_back(itAmbiColl);
401 ATH_CHECK(rpcCabling->giveRDO_fromPRD(idVectToBeDecoded, rdoHashVec));
405 ATH_MSG_DEBUG(
"*** " << nPrepRawData <<
" PrepRawData registered");
411 return StatusCode::SUCCESS;
416 const std::vector<uint32_t>& robIds,
bool firstTimeInTheEvent)
const {
420 int sizeVectorRequested = robIds.size();
421 ATH_MSG_DEBUG(
"Decode method called for " << sizeVectorRequested <<
" ROBs");
423 std::vector<uint32_t> robIdsToBeDecoded{};
424 robIdsToBeDecoded.reserve(robIds.size());
426 if (firstTimeInTheEvent) {
430 ATH_MSG_DEBUG(
"Whole event has already been decoded; nothing to do.");
431 return StatusCode::SUCCESS;
438 robIdsToBeDecoded.push_back(robid);
442 if (robIdsToBeDecoded.empty()) {
443 ATH_MSG_DEBUG(
"All requested ROBs have already been decoded; nothing to do.");
444 return StatusCode::SUCCESS;
446 ATH_MSG_DEBUG(robIdsToBeDecoded.size()<<
" ROBs have not yet been decoded and will be decoded now.");
449 for (
uint32_t robid : robIdsToBeDecoded)
457 if (state.
m_decodedRobIds.size() == rpcCabling->giveFullListOfRobIds().size())
462 ATH_MSG_DEBUG(
"Stored empty container. Decoding RPC RDO into RPC PrepRawData is switched off");
463 return StatusCode::SUCCESS;
469 ATH_MSG_DEBUG(
"Retrieving Rpc PAD container from the store");
471 if (!rdoContainerHandle.isValid()) {
473 return StatusCode::SUCCESS;
478 if (rdoContainerHandle->empty()) {
480 ATH_MSG_DEBUG(
"Empty pad container - no rpc rdo in this event ");
481 return StatusCode::SUCCESS;
486 std::vector<IdentifierHash> rdoHashVec;
487 rdoHashVec.reserve(13 * robIdsToBeDecoded.size());
488 ATH_CHECK(rpcCabling->giveRDO_fromROB(robIdsToBeDecoded, rdoHashVec));
491 bool processingetaview =
true;
492 bool processingphiview =
false;
494 processingetaview =
false;
497 int ipad{0}, nPrepRawData{0}, nPhiPrepRawData{0}, nEtaPrepRawData{0};
498 if (processingphiview){
501 ATH_MSG_DEBUG(
"*** Processing "<<(processingetaview?
"eta" :
"phi")<<
" view ");
506 for (
const IdentifierHash& padHashId : rdoHashVec) {
507 const RpcPad* rdoColl = rdoContainerHandle->indexFindPtr(padHashId);
509 ATH_MSG_DEBUG(
"Requested pad with online id "<< padHashId <<
" not found in the rdoContainerHandle.");
514 <<
", with " << rdoColl->
size() <<
" CM inside ");
516 processingphiview, nPrepRawData, rdoHashVec,
false));
519 if (processingetaview) {
520 processingetaview =
false;
521 processingphiview =
true;
522 nEtaPrepRawData = nPrepRawData;
523 ATH_MSG_DEBUG(
"*** " << nEtaPrepRawData <<
" eta PrepRawData registered");
525 processingphiview =
false;
526 nPhiPrepRawData = nPrepRawData - nEtaPrepRawData;
527 ATH_MSG_DEBUG(
"*** " << nPhiPrepRawData <<
" phi PrepRawData registered");
530 ATH_MSG_DEBUG(
"*** " << nPrepRawData <<
" PrepRawData registered");
537 return StatusCode::SUCCESS;
542 bool& processingetaview,
bool& processingphiview,
int& nPrepRawData,
543 const std::vector<IdentifierHash>& idVect,
544 bool doingSecondLoopAmbigColls)
const {
549 ATH_MSG_DEBUG(
"***************** Start of processPad eta/phiview "<< processingetaview <<
"/" << processingphiview);
554 ATH_MSG_DEBUG(
"***************** for Pad online Id "<< padId <<
" m_logic sector ID " << sectorId);
561 IdentifierHash rpcHashId{0};
570 bool highPtCm =
false;
572 uint16_t cmaId = coinMat->onlineId();
573 ATH_MSG_DEBUG(
"A new CM here n. "<< icm <<
" CM online ID " << cmaId<<
" with n. of hits = " << coinMat->size()
574 <<
", empty: "<<coinMat->empty());
578 }
else if (cmaId >=4) {
584 ATH_MSG_DEBUG(
" eta view = " << etaview<<
", processingetaview: "<<processingetaview
585 <<
", processingphiview: "<<processingphiview);
587 if (processingetaview && !etaview){
589 }
else if (processingphiview && etaview) {
592 if (coinMat->empty()) {
602 unsigned short overlap = 99;
609 ATH_MSG_DEBUG(
"RpcFiredChannel: bcid " << rpcChan->bcid() <<
" time " << rpcChan->time()
610 <<
" ijk "<< rpcChan->ijk() <<
" ch " << ( rpcChan->ijk() < 7 ? rpcChan->channel() : -1));
613 bool triggerHit =
false;
623 solvePhiAmb_thisHit =
false;
624 reduceCablOvl_thisHit =
false;
625 ATH_MSG_DEBUG(
"RpcFiredChannel: it's a triggerHit or a lowPt coinc. in a high pt CM \n"
626 <<
" ijk = " << rpcChan->ijk() <<
" isHighPtCM " << highPtCm
627 <<
" thr/ovl = " <<
threshold <<
"/" << overlap);
632 std::vector<Identifier> digitVec{
m_rpcRdoDecoderTool->getOfflineData(rpcChan, sectorId, padId,
633 cmaId, time, rpcCabling.cptr())};
636 int nMatchingEtaHits{0}, nDuplicatePhiHits{0};
637 bool unsolvedAmbiguity{
false}, notFinished{
true};
646 while (notFinished) {
648 ATH_MSG_DEBUG(
"size of the corresponding list of ID = " << digitVec.size());
649 if (digitVec.empty()) {
663 if (!idVect.empty() &&
std::find(idVect.begin(), idVect.end(), rpcHashId) == idVect.end()) {
668 bool hasAMatchingEtaHit = 0;
671 if ((oldIdTrg !=
parentId) || !collectionTrg) {
675 <<
" hash = " << rpcHashId);
680 }
else if ((oldId !=
parentId) || !collection) {
692 bool duplicate =
false;
693 if (reduceCablOvl_thisHit) {
694 ATH_MSG_VERBOSE(
"Check for duplicates in coll. with size "<< collection->size());
700 hasAMatchingEtaHit =
false;
704 float previous_time = rpc->time();
706 if (time < previous_time) {
708 ATH_MSG_DEBUG(
"time of the prd previously stored is now updated with "
709 <<
"current hit time: "<< previous_time <<
" -> " << rpc->time());
717 if (processingphiview && solvePhiAmb_thisHit && !unsolvedAmbiguity && !idHelper.
measuresPhi(existId) &&
720 hasAMatchingEtaHit =
true;
728 if (hasAMatchingEtaHit)
732 if (processingphiview && duplicate)
738 if (solvePhiAmb_thisHit && !etaview){
740 <<
" hasAMatchingEtaHit = "<< hasAMatchingEtaHit);
747 ATH_MSG_VERBOSE(
" solvePhiAmb_thisHit: "<<solvePhiAmb_thisHit<<
", processingetaview:"<<processingetaview
748 <<
", processingphiview: "<<processingphiview<<
", hasAMatchingEtaHit: "<<hasAMatchingEtaHit
749 <<
", unsolvedAmbiguity: "<< unsolvedAmbiguity);
750 if ( !solvePhiAmb_thisHit || processingetaview ||
751 (processingphiview && (hasAMatchingEtaHit || unsolvedAmbiguity))) {
752 if (unsolvedAmbiguity) {
753 if (idVect.empty()) {
758 ATH_MSG_DEBUG(
"unsolvedAmbiguity is true, adding collection with hash = "
759 << rpcHashId <<
" to ambiguous collections vector");
762 ambiguousCollections.insert(rpcHashId);
763 ATH_MSG_DEBUG(
"collection not yet processed; added to ambiguous "
764 <<
"collection vector; going to the next offline channel ID");
766 }
else if (!doingSecondLoopAmbigColls) {
767 ambiguousCollections.insert(rpcHashId);
768 ATH_MSG_DEBUG(
"collection already processed and doingSecondLoopAmbigColls=false; added to ambiguous "
769 <<
"collection vector; going to the next offline channel ID");
772 ATH_MSG_DEBUG(
"collection already processed and doingSecondLoopAmbigColls=true; trying to store data even if unsolvedAmbiguity");
782 hasAMatchingEtaHit =
false;
786 <<
"> inconsistent with the geometry of detector element <"
788 <<
"> =>>ignore this hit /// there are unmasked channels in BOG");
791 <<
"> inconsistent with the geometry of detector element <"
806 std::vector<Identifier> identifierList{
channelId};
812 double errPos = stripWidth / std::sqrt(12.0);
815 mat *= errPos * errPos;
818 int ambiguityFlag = 0;
819 if (solvePhiAmb_thisHit) {
820 if (processingetaview){
823 if (unsolvedAmbiguity){
824 ambiguityFlag = digitVec.size();
825 }
else if (hasAMatchingEtaHit){
826 ambiguityFlag = nMatchingEtaHits;
833 std::optional<double> StripTimeFromCool = readHandle->getStripTime(
channelId);
834 if (StripTimeFromCool) {
835 time -= (*StripTimeFromCool);
842 auto newCoinData = std::make_unique<RpcCoinData>(
channelId, rpcHashId,
843 std::move(pointLocPos), std::move(identifierList),
844 std::move(
mat), descriptor, time,
845 ambiguityFlag, rpcChan->ijk(),
threshold, overlap, cmaId, padId, sectorId,
849 ATH_MSG_DEBUG(
" Adding RpcCoinData @ "<< newCoinData.get() <<
" to collection "
852 newCoinData->setHashAndIndex(collectionTrg->identifyHash(),
853 collectionTrg->size());
854 collectionTrg->push_back(std::move(newCoinData));
858 <<
"ambiguityFlag = " << ambiguityFlag);
860 auto newPrepData = std::make_unique<RpcPrepData>(
channelId, rpcHashId,std::move(pointLocPos),
861 std::move(identifierList),
862 std::move(
mat), descriptor, time, ambiguityFlag);
865 ATH_MSG_DEBUG(
" Adding digit @ "<< newPrepData.get() <<
" to collection "
868 newPrepData->setHashAndIndex(collection->identifyHash(),
870 collection->push_back(std::move(newPrepData));
879 ATH_MSG_VERBOSE(
"processingphiview:"<<processingphiview<<
", nMatchingEtaHits:"<<nMatchingEtaHits
880 <<
", nDuplicatePhiHits, unsolvedAmbiguity: "<<unsolvedAmbiguity<<
", solvePhiAmb_thisHit : "
881 << solvePhiAmb_thisHit);
882 if ((processingphiview && (nMatchingEtaHits == 0)) && (nDuplicatePhiHits == 0) &&
883 (!unsolvedAmbiguity) && (solvePhiAmb_thisHit)) {
884 unsolvedAmbiguity =
true;
888 ATH_MSG_DEBUG(
"No eta prepData matching any phi hit from this CM hit \n"
889 <<
"loop once again and store all phi digits potentially "
890 "generating this CM hit");
891 }
else if (unsolvedAmbiguity)
899 ATH_MSG_DEBUG(
"***************** Stop of processPad eta/phiview "
900 << processingetaview <<
"/" << processingphiview
901 <<
"***************** for Pad online Id " << padId
902 <<
" m_logic sector ID " << sectorId);
904 return StatusCode::SUCCESS;
908 State& state)
const {
911 return StatusCode::SUCCESS;
914 ATH_MSG_DEBUG(
"Retrieving Nrpc RDO container from the store");
916 if (!rdoNrpcContainerHandle.isPresent()) {
918 <<
" container failed !");
919 return StatusCode::FAILURE;
922 if (rdoNrpcContainerHandle->empty()) {
924 ATH_MSG_DEBUG(
"Empty NRPC RDO container - no nrpc rdo in this event ");
925 return StatusCode::SUCCESS;
927 ATH_MSG_DEBUG(
"Not empty NRPC RDO container in this event ");
930 if (!readCdo.isValid()) {
932 <<
" from the conditions store");
933 return StatusCode::FAILURE;
938 for (
const xAOD::NRPCRDO* nrpcrdo : *rdoNrpcContainerHandle) {
941 translateCache.
subDetector = nrpcrdo->subdetector();
942 translateCache.boardSector = nrpcrdo->boardsector();
943 translateCache.board = nrpcrdo->board();
944 translateCache.channelId = nrpcrdo->channel();
946 if (!readCdo->getOfflineId(translateCache, msgStream()) ||
947 !readCdo->convert(translateCache, chanId,
false)) {
949 return StatusCode::FAILURE;
957 std::vector<Identifier> identifierList{chanId};
961 <<
" global position "
968 const double stripWidth = descriptor->
StripWidth(
971 const double errPos = stripWidth / std::sqrt(12.0);
974 mat *= errPos * errPos;
976 int ambiguityFlag = 0;
978 const float time = nrpcrdo->time();
980 const float timeoverthr = nrpcrdo->timeoverthr();
982 const IdentifierHash rpcHashId =
m_idHelperSvc->moduleHash(chanId);
983 auto newPrepData = std::make_unique<RpcPrepData>(chanId, rpcHashId, pointLocPos, identifierList,
mat,
984 descriptor, time, timeoverthr, 0, ambiguityFlag);
986 newPrepData->setHashAndIndex(collection->
identifyHash(),
988 collection->
push_back(std::move(newPrepData));
990 return StatusCode::SUCCESS;
995 bool highPtCm,
bool& triggerHit,
996 unsigned short&
threshold,
unsigned short& overlap,
997 bool& toSkip)
const {
1000 if ((highPtCm && rpcChan->
ijk() < 2) || (rpcChan->
ijk() > 5)) {
1010 if (rpcChan->
ijk() == 7) {
1015 if (rpcChan->
ijk() == 6) {
1017 ATH_MSG_VERBOSE(
"This hit: ijk = " << rpcChan->
ijk() <<
"in "<<(highPtCm ?
"high" :
"low")
1018 <<
" pT CM, bcid is " << rpcChan->
bcid()<<
" time is " << rpcChan->
time()
1019 <<
" ch " << rpcChan->
channel());
1021 while (itDnext != itD_end) {
1023 ATH_MSG_VERBOSE(
"Next hit: ijk = " << rpcChanNext->
ijk() <<
"in "<<(highPtCm ?
"high" :
"low")
1024 <<
" pT CM, bcid is " << rpcChan->
bcid() <<
" time is " << rpcChanNext->
time()
1025 <<
", ch: "<<( rpcChanNext->
ijk() < 7? rpcChanNext->
channel() : -1));
1027 if (rpcChanNext->
ijk() == 7) {
1028 if (rpcChanNext->
bcid() == rpcChan->
bcid() && rpcChanNext->
time() == rpcChan->
time()) {
1029 ATH_MSG_VERBOSE(
"bdid/tick match; assigning thr/overlap = " << rpcChanNext->
thr() <<
"/" << rpcChanNext->
ovl());
1031 overlap = rpcChanNext->
ovl();
1033 ATH_MSG_WARNING(
"ijk =7 after a ijk = 6 BUT bdid/tick don't match - will not assign threshold/overlap ");
1037 if (rpcChanNext->
ijk() == 6) {
1041 ATH_MSG_WARNING(
"RPC cm hit with ijk = 6 not followed by ijk = 6 or 7 - will not assign threshold / overlap");
1052 << rpcChan->
ijk() <<
" threshold / overlap = " <<
threshold